Loop through first row of each named range in one code block - vba

So I've had to write two almost identical code blocks to loop through my two named ranges. However, I know that the named ranges will always be the same size and shape as each other and even start in the same column (different rows) and they also need to be pasted into two columns next to each other so I feel like this should be possible in one code block but can't even think how to start attacking it. E.g. Cash Payments Monthly is in array A10:D20 and P&L Payments Monthly is in array A40:D50.
Anyone got any ideas, please and thank you?
For Each Row In Range(Names("Cash_Payments_Monthly")).Rows
LastRow = wsDashData.Cells(Rows.Count, 14).End(xlUp).Row
Row.Copy
wsDashData.Range("n" & LastRow + 1).PasteSpecial _
Paste:=xlPasteValues, _
Transpose:=True
Next Row
For Each Row In Range(Names("PL_Payments_Monthly")).Rows
LastRow = wsDashData.Cells(Rows.Count, 15).End(xlUp).Row
Row.Copy
wsDashData.Range("o" & LastRow + 1).PasteSpecial _
Paste:=xlPasteValues, _
Transpose:=True
Next Row

Assuming you have other named ranges in your workbook, you should start by creating a whitelist array of named ranges that you WOULD like to search, then iterate through that array, embedding a single copy of your existing code in that loop...
Dim myranges()
Dim c As Integer 'counter
myranges = Array("Cash_Payments_Monthly", "PL_Payments_Monthly")
For c = 0 To UBound(myranges)
For Each Row In Range(myranges(c)).Rows
...the rest of your code, but just one instance of it :-) ...
Next c

Related

Excel VBA Transposing is Resulting in Multiple Entries

So I'm trying to transpose data with two rows and 238 columns to a list (two columns and 238 rows) that I can then filter to remove the rows that have cells with no values next to them. I'm pretty novice when it comes to VBA, so it took me a while to get the code to work for the transpose function, but when I finally got the data transposed, each column became two duplicate rows (instead of just one), and when it reaches the last category (last column in original configuration), the duplicates continue for about 300 rows. I'm not sure where I went wrong, but I hope the issue is obvious so someone can give me a quick answer haha
Here is the code that I have:
Sub Transpose()
ThisWorkbook.Worksheets("Training List by Position").Range("A4:B10000").Clear
Dim Range1 As Range, Range2 As Range, Rng As Range
Dim rowIndex As Integer
Set Range1 = ActiveWorkbook.Worksheets("Training List by Position").Range("A1:IB2")
Set Range2 = ActiveWorkbook.Worksheets("Training List by Position").Range("A4:B300")
columnIndex = 0
Application.ScreenUpdating = False
For Each Rng In Range1.Columns
Rng.Copy
Range2.Offset(columnIndex, 0).PasteSpecial Paste:=xlPasteAll, Transpose:=True
columnIndex = columnIndex + Rng.Rows.Count
Next
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub
I think you're over-complicating this a bit - why do you need anything more than this?
Range("A1:IB2").Copy
Range("A4").PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
dwirony's answer is the best to solve your problem, but if you want to know why each column is duplicating, it happens because rng.rows.count is adding 2 (two) to columnIndex every loop, since in your original data there are two rows of every column.
also it does fill 300 rows because you're asking excel to fill the entire range of Range2 variable, every iteration it pastes to A4:B300, goes down two rows and repeat

Trying to copy a formula down an entire column to the last row of data in an adjacent column

I am a new VBA user, and I am trying to create a VBA code to copy a single Vlookup formula down an entire column to the last row of data in an adjacent column. I don't want to specify a specific range, because I intend to use this macro with multiple different files that have different row ranges, so I am looking for a code that will simply copy down to the last value in an adjacent column.
I have tried looking at other similar questions and answers on this website, but none of the solutions that I have found have been working, and I would really appreciate some help!
Here is my code that I currently have:
' Section5 Macro
ActiveCell.FormulaR1C1 = _
"=VLOOKUP(RC[6],'[PERSONAL.XLSB]Task and Sections'!R2C1:R254C2,2,FALSE)"
Range("C2").Select
Selection.Copy 'Copy Vlookup Formula
Dim lastRow As Long
lastRow = Range("B" & Rows.Count).End(xlUp).Row
Range("C3").AutoFill destination:=Range("C3:C" & lastRow) 'Specify range for Column C based off of row count in Column B
Application.CutCopyMode = False
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False 'Paste Vlookup equation down the column
End Sub
The formula I want to copy is "=VLOOKUP(RC[6],'[PERSONAL.XLSB]Task and Sections'!R2C1:R254C2,2,FALSE". The column that I want to copy this formula down is column C (in all rows except C1 which is the Header). The column that I want to refer to for row length is the adjacent column B.
Currently I am getting an error that says "Compile error: Named argument not found".
Any help would be greatly appreciated!
Thank you,
As pointed in the comment, you had a simple typo ("desination")... Nevertheless, your code doesn't seem to work even when this is fixed.
There's a much simpler approach. Try this:
Sub FillWithFormula()
Dim lastRow As Long
lastRow = Range("B" & Rows.Count).End(xlUp).Row
Range("C2:C" & lastRow).FormulaLocal = "=B2*2"
End Sub
Notice that I replaced your formula with a simpler one (independent of external data) so I could verify that the routine works.
Here.
Sub thing()
Dim lastRow As Long
lastRow = Cells(Rows.Count, 2).End(xlUp).Row
Range("C3:C" & lastRow).FormulaR1C1 = "=VLOOKUP(RC[6],'[PERSONAL.XLSB]Task and Sections'!R2C1:R254C2,2,FALSE)"
Range("C3:C" & lastRow).Value = Range("C3:C" & lastRow).Value
End Sub
Simpler, more elegant. Hasn't this kind of thing been solved like a million times all around the internet? Anyway, copy-paste is the slowest thing you can do in a macro. Avoid it. Just set the values of a range to be the values of the range. :)
Also, you can assign a formula to a whole range.

How would I go about searching for, and then importing values of a known structure from one excel file to another?

I have an excel file exported from another program with a bunch of data in it. From all of this data, I only need certain pieces of it. The data I need looks like this (with different numbers than 1.111 and 4.444):
C1: 1.111 4.444
C2: 1.111 4.444
...
C10: 1.111 1.111
The file has upwards of 30 sets of this data, all contained in columns A to C, except I do not know which rows they start at and end at. What I want to do is search the excel file for this data, and paste it into another file side-by-side (where C1's, C2's, etc. numbers line up in the same row.)
A YouTube tutorial gave me the following code that would be used to grab values at a known location in the file:
Sub ImportFluidData()
Dim FileNames As Variant
Dim i As Integer
Application.ScreenUpdating = False
Range("A1").Select
FileNames = Applcation.GetOpenFilename(FileFilter:="Excel Filter (*Analysis.xlsx), *.xlsx", Title:="Open Files(s)", MultiSelect:=True)
For i = 1 To UBound(FileNames)
Workbooks.Open FileNames(i)
Range(------------------------).Select
Selection.Copy
Windows("Fluid Properties.xlsm").Activate
Selection.PasteSpecial Paste:=xlPasteAll, Transpose:=True
Workbooks.Open FileNames(i)
ActiveWorkbook.Close SaveChanges:=False
ActiveCell.Offset(0, 1).Activate
Next i
End Sub
My problem is that instead of a known range, I need to replace Range(-------------).Select with a statement that searches for and selects the data descried above. How would I go about searching for and selecting such data? I quite literally just started using VBA today, so please try to avoid any VBA-specific jargo.
Thanks for the help!
Edit: the tutorial was for importing data at a known spot in multiple files, so that's why it's set up for looping through multiple files. I only need to search through one file, which will likely make the code a lot shorter.
If I understood well, you find yourself in a situation in which you have a uniform set of data that can be in a random position of a column (let's do the example with the column B):
If this is the case, then what you need to do is to find the start and the end point of your range. Which means:
Find your start point ##:
Dim startRow As Long: startRow = Range("B1").End(xlDown).Row
Find your end point
Dim endRow As Long: endRow = Range("B" & startRow).End(xlDown).Row
Select your range
Range("B" & startRow & ":B" & endRow).Select
The above will select the range B9:B14, but if there were 10 rather than 15 or 20 elements it would have found them as well.
Looping through the 30+ sets
#pnuts comment made me realized I had "partially" read the question, I report here his comment:
I think there may be 30+ instances all in the same two columns - ie maybe as the populated set you show (though possibly 10 rows rather than 6) and then 29+ other such sets, spaced apart by a variable number of blank rows.
In that case you should first of all define the last row of the sheet, i.e.
Dim lastRowOfSheet As Long: lastRowOfSheet = Range("Z1").End(xlDown).Row '<-- I assume in column Z there's nothing, please choose it accordingly
Hence, you need to Loop through the various datasets until you don't find the last one. which means:
'first static definitions outside the loop
Dim startRow As Long: startRow = Range("B1").End(xlDown).Row
Dim endRow As Long: endRow = Range("B" & startRow).End(xlDown).Row
Do While endRow <> lastRowOfSheet
'************SELECTING THE DATA SET**************
Range("B" & startRow & ":B" & endRow).Select
'do what you need to do after having selected the proper range
'***********************************************
'last re-definition before to loop again
startRow = Range("B" & endRow +1).End(xlDown).Row
endRow = Range("B" & startRow).End(xlDown).Row '<-- if this touches the end, it means it was the last dataset so we will go out of the loop
Loop

VBA query: using clipboard data to filter

I'm using multiple worksheets in Excel to create a database of candidates undergoing some technical training. Each time a candidate is added to the 'database' they are assigned a unique number, for example "2015-0001". When they call to pay their deposit, I'm using a data input table for the telephone operator to note down the details, and it looks up the unique number for the candidate. I then want to filter the main database for the candidate by their number and paste in the confirmed details of the deposit.
My query is this: how do I write the code that copies the candidate number data from the cell on worksheet 1 and then uses that data (irrespective of its value) to filter worksheet 2?
I'm new to macros and have been using "record macro" to generate code which I then edit and learn as I go. So, apologies if this looks extremely clunky. Using record, the filter command simply takes the example text I'm using (in this case 2015-0011), not replacing it with the revised value when the Deposit input table is changed and the macro is run. Am I right to think that I need to use a String?
Thanks in advance. RLC
Sub Confirm_Deposit()
'
' Confirm_Deposit Macro
'
'
Sheets("Take Deposit").Select
Range("C5").Select
Selection.Copy
Sheets("CIP Candidates").Select
ActiveSheet.Range("$A$6:$AK$2507").AutoFilter Field:=1, Criteria1:= _
"2015-0011" <---------------- ISSUE
Sheets("Take Deposit").Select
Range("C6:C8").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("CIP Candidates").Select
Range("A6").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Offset(0, 20).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=True
Application.Run _
"'CIP Spreadsheet RLC (with Macros).xlsm'!ThisWorkbook.Clear_Filters"
etc.
This is a different approach that is less "Macro" based and more just simple cell manipulation using loops. It's very flexible. See what you think of the idea, then we can modify to your specific needs.
The part of this code that I would change immediately is selecting where the lookup value comes from. In this example, since I don't know your specifics, I saw you are using "C5" in the example above.
Sub Confirm_Deposit()
Dim source As String
Dim target As String
Dim lookupVal As String
Dim row As Long
Dim searchRow As Long
source = "Take Deposit" 'In case you have similar projects, you can just replace these lines.
target = "CIP Candidates"
lastSourceRow = Sheets(source).Range("A" & Rows.Count).End(xlUp).row
lastTargetRow = Sheets(target).Range("A" & Rows.Count).End(xlUp).row
lastTargetCol = Sheets(target).Cells(1, Columns.Count).End(xlToLeft).Column
lookupVal = TextBox1.Text 'Set the lookupVal from whatever source you choose. I like ComboBoxes when I can.
For searchRow = 2 To lastSourceRow
If Sheets(source).Cells(searchRow, 3).Text = lookupVal Then 'Searching through Source Sheet on Col "C"
Exit For
End If
Next searchRow
'This way, at the end of the search, you have the row number of the original source to be copied, instead of hard coding.
For row = 6 To lastTargetRow 'Loop through the Target Sheet
If Sheets(target).Cells(row, 3).Text = lookupVal Then 'Compare lookupVal to the Range being looped.
For col = 2 To lastTargetCol
Sheets(target).Cells(row, 3) = Sheets(source).Cells(searchRow, col) 'Copies contents from Row 5 of source sheet.
Next col
End If
Next row
End Sub
EDIT: Made lookup Row dynamic instead of hard coded to row 5
Been a while but will this do the trick?
ActiveSheet.Range("$A$6:$AK$2507").AutoFilter Field:=1, Criteria1:= _
Sheets("Take Deposit").Cells(5,3).Value
or
ActiveSheet.Range("$A$6:$AK$2507").AutoFilter Field:=1, Criteria1:= _
Sheets("Take Deposit").Range("C5").Value
theres no need to select and copy the value. You can just reference the Cells Value.

Excel/VBA How to move data from one worksheet to another after last used cell?

I've got a workbook with 9 different worksheets in which 1 of the sheets if 4 of them combined into 1 sheet for further comparison which from a copy and paste point of view is easy but im looking at it from an automation point of view as the length of rows can increase and decrease depending on data.
i need sheet A to copy in first on the left hand side on columns A,B,C which is then followed by sheet B which is inserted directly below sheet a on the same columns. Sheets C and D are similar but on the right of the first 2 sheets in columns H,I,J so they can be compared
I've tried to be clever and run multiple for loops on each sheet copying the data over to this work sheet with A&B sharing a global variable and C&D holding another so they went into the right places. Issue i had with this is long running times and mainly crashing on excel.
i also tried copying an pasting all the columns but didn't work as they vary in length so cant be recorded.
I finally tried a way of setting an row counter to be the last used row of the previous sheet to work but it also resulted in crashing.
Sheets("Income").Select
Dim xell As Range
For Each xell In Range("A1:A3005")
If Not xell.Value = "" Then
xell.EntireRow.Copy
Sheets("Workings").Select
Cells(z, "A").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=True, Transpose:=False
Sheets("Income").Select
z = z + 1
End If
Next xell
This is an example of my first attempt with the other sheets code being similar anyone got an idea of how to copy 4 work sheets into 1 in the desired destinations>?
Some things:
First, stop using Sheets().Select. There is no need, it will just flicker madly. You can safely use Sheets("Workings").Cells(...) to reference Cells on a Sheet.
Second, Cells() takes only integers as parameters, not "A". At best, this will be converted to 65 (ASCII) which is wrong for your case. Use Cells(z, 1) instead of Cells(z, "A").
Third, z needs to start at 1, not 0. You didnt initialize it anywhere so it will start as 0, which crashes.
You could try this:
Sub CopyIt()
allSheets = Array(Array(sheets("A"), sheets("B")), Array(sheets("C"), sheets("D")))
Set destSheet = sheets("Dest")
Set startRange = destSheet.Range("A1")
For Each doubleSheet In allSheets
For Each srcSheet In doubleSheet
Set firstEmpty = srcSheet.Columns(1).Find("")
If Not firstEmpty Is Nothing Then
RowCount = srcSheet.Columns(1).Find("").Row - 1
Range(srcSheet.Cells(1, 1), srcSheet.Cells(RowCount, 3)).Copy Destination:=startRange
Set startRange = startRange.Offset(RowCount, 0)
End If
Next
Set startRange = destSheet.Range("H1")
Next
End Sub