VBA code to count number of rows (in filtered data) & sum a relevant column in filtered source file - vba

I would like to get help on VBA codes to:
count the number of rows (which could be filtered) from a source file which I have opened and reported the number in a master file.
have the sum of a relevant column in the source file and report the value in a master file.
The reason for these questions is to make sure that the input source file has been completely copied into the master file.
Any help would be much appreciated.

dim endRow as integer
Range("a1").select
selection.End(xlDown).Select
endRow = activecell.row
This is assuming that all fields in that column will have values.
This also works with xlToRight and xlToLeft as long as there are values in each cell.

To count the non-blank non-hidden cells in Column A of Worksheet Sheet1, you can use this code:
WorksheetFunctions.Subtotal(103, Sheet1.Columns(1))
To do so in a Cell is very similar:
=SUBTOTAL(103, Sheet1!$A:$A)
(Of course, this will include your header row)
(SUBTOTAL(3, Sheet1!A:A) is the same as COUNTA(Sheet1!A:A) - using 103 instead is what makes it ignore the hidden/filtered-out rows)

Related

Copy Range Excluding Blank Cells - Paste to Another Sheet

Ok, back again!
I have tried to search throught this and other forums to find a similar solution, but everything Ive found is either just different enough that I cant figure out the application to my problem, or super complex, and I cant translate it! So Im hoping someone can help me here. Thanks in advance!!
Here is the scenario. I have a database that Im needing to add data to. Quote Number, PO Number,SubSystem Part Name, Vendor, Material, Price, Qty. Etc.
Long story short, and without getting into the context of why I did it this way (mostly because I think I would botch the explaination and be more confusing than helpful!) ... I have essentially 3 tables right next to each other.
Table 1 is columns H and I. These all have a formula similar to =if(isblank(J4),"",$I$1) Where I1 is the PO Number (which will remain the same for this set of entries.)
Table 2 is a pivot table in columns J through M. Using a slicer the user can select what sub systems they need for this PO. The pivot table will repopulate with the appropriate part numbers and unique information contained in another table.
Table 3 is a regular table in columns N through R. These columns have some formulas like above that pull from a single cell (for entering the date), some pull information from another table based on information in column J via a VLOOKUP, and some information is entered manually.
That might be too much information, but better to have it and not need it eh?
So heres the goal. With a VBA macro, I want to copy the data and paste it onto another sheet, at the bottom of a database. The trick is, because that whole setup above runs based on information coming from a pivot table, the list changes length constantly. It will never be longer than a certain length (still TBD) but will almost always be shorter. I can copy the whole thing, and have it paste to another sheet below the last entry... but it pastes below the last empty cell in the database sheet. What I mean is this:
The longest the table could be would be range H4:R38 for example. So I copy that, paste it to Sheet2 starting at cell A2. Upon further inspection, we see that there is only actual data in the range H4:R11. However, when we pasted it to Sheet2 it pasted the whole range H4:R38. When I run the macro again, instead of the new data set being pasted to row A10 (the row after where the data should have ended), it pastes to something like row 36... because its pasting below all the blank cells.
I have no idea what to do or where to start. Any help would be greatly appreciated! Thanks so much!
Code I've Tried:
Dim fabricationrange As Range
Dim destination As Range
Dim LastBBUFabDatabaseRow As Long
Worksheets("Sub Systems").Range("h4:r38").Copy
With ThisWorkbook.Sheets("BBU Fab. Database")
Worksheets("bbu fab. database").Range("z" & Rows.Count).End(xlUp).Offset(1).PasteSpecial Paste:=xlPasteValues
Range("b" & Rows.Count).End(xlUp).Offset(1).PasteSpecial xlPasteValuesAndNumberFormats
lastbbufabdatabserow = .Cells(.Rows.Count, 2).End(xlUp).Row = 1
Set destination = .Cells(LastBBUFabDatabaseRow, 2)
destination.Value = PasteSpecial.Values
End With
Untested but here's a brute-force approach to locating the first empty row:
set rngDest = ThisWorkbook.Sheets("BBU Fab. Database").rows(2) '<< start here
do while application.counta(rngDest) > 0
set rngDest = rngDest.offset(1, 0) 'next row
loop
Worksheets("Sub Systems").Range("H4:R38").Copy
rngDest.cells(1).PasteSpecial xlPasteValuesAndNumberFormats '<< paste to col A

VBA: How to keep my csv format when transferring excel data to it?

I have a csv file that I have separated based on commas. I'm using a csv file because I'm using it as a "master" file to hold a lot of information but I would prefer columns rather than having it separated by commas.
So the code I need is to be able to run a macro that will take cells from my "copy" excel workbook, and move append it to where the new blank cells begin at the bottom of my "master" csv file.
For example:
A B C
Week Time Month
3 09:03 March
My Master.csv will have the same column headings and I will want to continually update the Master.csv when I get new info from my copy.xlsx which is updated weekly.
Sub move2()
Dim x As Workbook
Dim y As Workbook
Dim vals As Variant
'Open workbooks
Set x = Workbooks.Open("C:\Users\wra\Desktop\macro test\copy")
Set y = Workbooks.Open("C:\Users\wra\Desktop\macro test\Master.csv")
'Store value in variable
vals = x.Sheets("copy").Range("A5").Value
'Use the variable to assign a value to the other file/sheet:
y.Sheets("Master").Range("A3").Value = vals
'Close x:
x.Close
End Sub
I know this code doesn't do what I want full yet (only takes one value and adds it to a specific place in the master.csv, but it's a start I guess.
The thing is, when I run this macro, information from my copy.xlsx is moved to the Master.csv, BUT the master.csv gets reformatted from columns to text.
So after the macro is run it looks like the following:
A
Week,Time,Month
3,09:03,March
All the data goes back to one column and the Text to Columns function I used before hand is removed.
How can I prevent this from happening? And if anyone can help with the next part of code (where I want it to append to the bottom of my master.csv data, that would be awesome.
Hope this was clear, thanks in advance!
As David said, use Workbooks.OpenText to ensure your master file is opened correctly, e.g.:
Set y = Workbooks.OpenText("C:\Users\wra\Desktop\macro test\Master.csv", DataType:=xlDelimited, Comma:=True)
To append to the bottom of the master file, you will need to find the last row in the file, and input your data below that. There are many ways to find the last row in Excel, but one method is to do the following:
myLastRow = y.Sheets("Master").Cells(Rows.Count, 1).End(xlUp).Row
which finds the last row in in the first column of the "Master" sheet. The new data could then be copied in like so:
y.Sheets("Master").Cells(myLastRow + 1, 1).Resize(number_rows, number_cols).Value = vals

Compare Cell Data and Copy

I found this great snip of code and I am trying to manipulate it to work for me, but I just can't seem to get it. Unfortunately I haven't been able to get my head around it to fully understand it, which doesn't help. So I turn to you. I need to evaluate a column of cells and look for either similarities or differences. If a cell in sheet 1 column 1 is not the same as any of the cells in sheet 2 column 1, I want to copy the entire row into sheet 1 at the bottom of the used area. I've gotten this to the point where what you see will copy the correct first cell, but I can't manipulate it to copy the entire row. I think because of how the 'With' is structured but I need to try to stay away from doing loops since there is over 30k cells to evaluate.
Going down the road I will also be wanting to look for duplicates using the same method above, and if there is a duplicate, compare the adjacent cells for differences and if there is a difference, move the existing data into a comment and move the new data into the existing cell.
Any and all advice is, as always, very appreciated.
Sub Compare_Function()
Call Get_Master_Cell_Info
Application.ScreenUpdating = False
With Sheets("Update").Range(Cells(4, 1), Cells(Rows.Count, 1).End(xlUp)).Offset(, 1)
.Formula = "=VLOOKUP(A4,'New Master Data 6.1'!A:A,1,FALSE)"
.Value = .Value
.SpecialCells(xlCellTypeConstants, 16).Offset(, -1).Copy Sheets("New Master Data 6.1").Range("A" & Rows.Count).End(xlUp).Offset(1)
.ClearContents
End With
Application.ScreenUpdating = True
End Sub
Quick line by line breakdown
This just takes the entire used range from cells A4 to the last used cell in columnA then offsets it by one column so B4:Bx (x is the last used row in column A)
With Sheets("Update").Range(Cells(4, 1), Cells(Rows.Count, 1).End(xlUp)).Offset(, 1)
This puts the formula in all cells so it looks up A4,A5,A6, etc in master sheet, returns the value in the master sheet or an error if its not found. It then copies the values over so they are hardcoded in
.Formula = "=VLOOKUP(A4,'New Master Data 6.1'!A:A,1,FALSE)"
.Value = .Value
Specialcells looks for constants (all cells) and value 16 which means error cells (ie cells don't exist) offsets by -1 (so column A) and copies to new sheet column A at rows.count+1
.SpecialCells(xlCellTypeConstants, 16).Offset(, -1).Copy Sheets("New Master Data 6.1").Range("A" & Rows.Count).End(xlUp).Offset(1)
You might also want to do this after you .clearcontents so you don't get all the error cells in column B
to fix it just change the copied range to .entirerow so
.SpecialCells(xlCellTypeConstants, 16).entirerow.Copy Sheets("New Master Data 6.1").Range("A" & Rows.Count).End(xlUp).Offset(1)
You will also copy the errors in column B but with this structure there is no getting around that. Can always erase them from the master sheet after.
Also note this code will overwrite any data you have stored in column B.
One more note this code depends on the sheet update being active, it won't run otherwise since your cells function inside your range needs the worksheet explicitly stated, as does your rows.count. You would be better wrapping the whole thing in 2 withs, one for the sheet and one with the range (using .cells and .rows.counmt)

Run VBA format code on all sheets with different number of rows

VBA noob here needs a little bit of assistance. I cannot seem to find a solution or get something to work.
I've tried to simplify it as much as I could to get a proof of concept.
The basic idea is to format one cell (A1 say) with all borders, copy that format down across all data in the first sheet (A1:C10 for example), then do the same with data in subsequent sheets. What I'm struggling with is that subsequent sheets all have a different number of rows and anything I try just formats the additional sheets to the (A1:C10) of the original even if there is no data present.
Any help would be greatly appreciated.
What you need is a variable that identifies the last row of any given sheet. For instance
LastRow = Worksheets("Sheet1").cells(65000,1).end(xlup).row
Now you can loop through your cells
for i = 1 to LastRow
for j = 1 to 3
Worksheets("Sheet1").cells(i, j) (apply your formatting)
next j
next i
You can find the last row in a column by using this VBA code:
lastrow = Sheets("SheetName").Cells(rows.count,columnnumber).end(xlup).row
Change columnnumber to the number of the column you are looking in, for example column A = 1.

Getting a total copied set of rows in VBA and storing it in a variable

I asked this question a bit ago, but asked it incorrectly, and wasn't able to receive the best answer.
I have a fairly simple syntax question:
I'm trying to copy and paste n rows from one excel file to another. In addition, I'd like to store the total FILTERED copied rows into a variable. Can someone help me accomplish this?
For example:
'1) Activate CSV file, Apply Filter to Column B (Page Title) & uncheck "blanks" ("<>") filter
Windows("Test_Origin.xlsm").Activate
ActiveSheet.Range("$A$1:$J$206").AutoFilter Field:=2, Criteria1:="<>"
'2) Copy Filtered Lines with data (Excluding Row 1)
Range("B2:F189").Select
Selection.Copy
copiedRowTotal = Selection.Rows.Count <-- This doesn't give me the FILTERED rows
Thanks
dim i as long
i = Application.WorksheetFunction.Subtotal(2,worksheets("Sheet").Range("B2:F189"))
Gave you the description here
Getting a total copied set of rows in VBA and storing it in a variable
Try:
copiedRowTotal = Range("B2:B189").SpecialCells(xlCellTypeVisible).Count