Let’s say I have a rental car company and I have 12 sheets with 10 columns each and unknown amount of rows. Each sheet is holding information about cars rented. Below are the column headings for each spreadsheet
- A. Date rented
- B. Customer Name
- C. Customer Address
- D. Customer Phone
- E. Customer email
- F. Car Year
- G. Car Make
- H. Car Model
- I. Car Plate number
- J. Car Vin
I have a master sheet that I want to get specific information from all sheets and copy the cellValues of those sheets into the master sheet. I’m not familiar with VBA so Here is the sudocode of the loop I want to do:
For each sheet
For each row
Copy customer name, customer phone, car plate number into next available row on master sheet
In the master sheet, the columns would be respectively how I put them in the sudocode
- A. Customer Name
- B. Customer Phone
- C. Car Plate number
Can someone show me what the VBA macro code would be for this?
Disclaimer: this is not my actual information in my spreadsheet as what I am working on is confidential so I can’t provide screenshots. This is just example information that simulates what I want to do.
I've tried =HLOOKUP(B1,'Sheet1 (51)'!1:1048576,2:2,FALSE) but getting a value error or an NA error, depending on what range or values I try in the parameters. The way I was understanding the HLookup function is this:
lookup value is the column heading I'm looking for within the source sheet: for customer name I would but B2 for the lookup value
The table array would be the whole source sheet
The row array would be the row I'm getting the cell value from in the source sheet
range lookup is either T or F or nothing as it is optional. If i use True or False, I get the NA error if I use nothing I get the value error.
The idea is that once I get this formula working for one cell then expand it to one row then expand it to the loop i have in my sudocode for all rows within the source sheet, then expand it to look or go to the next source sheet.
You can accomplish this fairly easily by looping through all the available sheets, excluding the master sheet and setting the relevant range for each sheet. Then using the find function to get the last row of data in the master sheet to be able to append the next rows.
This should produce the desired result:
Sub MasterGrab()
Dim master As Worksheet
Dim subSheet As Range
Dim i As Integer
Dim lastRow As Long
Set master = Worksheets("MasterSheet")
x = Sheets.Count
lastRow = master.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row 'find last row on master sheet
lastRow = lastRow + 1
For i = 1 To x
If Not Sheets(i).Name = "MasterSheet" Then 'capture all sheets except MasterSheet
Set subSheet = Sheets(i).Range("A1:J" & ActiveSheet.Cells.SpecialCells(xlCellTypeLastCell).Row) 'set each sheet range to cover required data
For Each r In subSheet.Rows
master.Cells(lastRow, 1) = r.Cells(2) 'Customer name
master.Cells(lastRow, 2) = r.Cells(4) 'Customer phone
master.Cells(lastRow, 3) = r.Cells(9) 'Car Plate number
lastRow = lastRow + 1
Next r
End If
Next i
End Sub
It might be the most silly question in planet. how can I merge two cell values vertically in a repeated manner. as like this:
Column A and B has 400+ cells therefore it is impossible to do what I want to achieve manually.
Note: I want to merge B into A.
You can create a simple loop in VBA that runs through each cell in the data range then adds it to the output column
Sub Merge()
Dim data As Range
Dim cell As Range
Dim output As Range
Dim i As Integer
Set data = Range("A2:B4")
Set output = Range("D2")
i = 0
For Each cell In data
output.Offset(i, 0) = cell
i = i + 1
Next
End Sub
You can use the INDEX function to refer to each cell. If data is in A2:B4, this formula works in any column but must start in row 2 and can then be filled down:
=INDEX($A$2:$B$4,ROW()/2,MOD(ROW(),2)+1)
The formula uses the current row as a counter. On every even row it gets a value from the first column of data and on every odd row it gets a value from the second column of data. After every 2 rows it gets values from the next row of data.
This query is two fold. Any assistance would be much appreciated and unfortunately there is a lot of detail behind this so apologies for the great deal of text.
I am working on updating a 12 month trending report that pulls data from one sheet using a series of complex vlookups based on several criteria (Project, unique project id, Order, yr-month etc). Yes it would likely be easier to use pivot tables, but unfortunately because of the way this document is used the people with access to it want it to remain as is, from a format and function perspective but want the document sped up (takes roughly 5 minutes to calculate when ever something is changed.)
The data set is 36 columns by 50000 rows with 7 columns containing identifiers used to pull in specific data on the trending sheet
As it current sits on a monthly basis new data (approximately 6000 rows) of additional data is added.
I've added two macros to the document in an attempt to reduce user error
I am currently using the following code to take the order number remove the duplicates and then apply an index/match to pull in the relevant Project and then use countif to apply a unique key to the end of the project (using concatenate)
Sub ProjTrending1()
Dim s1 As Worksheet, s2 As Worksheet
'Defines S1 as a Worksheet
Set s1 = Sheets("All Data")
'Defines S2 as WorkSheet
Set s2 = Sheets("Workings")
'Defines LastR1
Dim LastR1 As Long, DataRange1 As Range
'Finds last row cell working sheet
LastR1 = s2.Range("A1").CurrentRegion.Rows.Count
'Takes Data from Order Column of defined data Sheet and copy & pastes it to Working Sheet Column B
s1.Range("J1:J" & LastR2).Copy s2.Range("A1")
'Removes Duplicates from Column B Working sheet
s2.Range("A2:A" & LastR1).RemoveDuplicates Columns:=2, Header:=xlNo
'Copies the formula from B2 and applies it to all cells in column B where column A has values
s2.Range("B2").Copy s2.Range("B2:B" & LastR1)
'Copies the formula from C2 and applies it to all cells in column C where column A has values
s2.Range("C2").Copy s2.Range("C2:C" & LastR1)
End Sub
The formula is column B is as follows
=INDEX('All Data'!E:E,MATCH(Workings!A2,'All Data'!J:J,0))
The formula in column C is as follows
=B2&COUNTIFS($B$2:B2,B2)
The data set in worksheet All Data is approx 50k rows long and will continue to grow. The issue I'm not running into is that this macro is starting to take a great deal of time to run because the information in column C is used as a unique identifier on the trending report.
Is this because I have a vast number of Vlookups on the trending tab (approx 20k) pulling data based on this or is there an issue with the macro I have created to create a unique identifier?
I've been looking at alternative ways in which I could draw the data through to the trending tab (dictionaries etc) with no luck so far. It would be much appreciated if someone could offer an alternative to 20k vlookups.
I have a current Sub that organizes data certain way for me and even enters a formula within the first row of the worksheet, but I am running into the issue of wanting it to be able to adjust how far down to fill the formula based on an adjacent column's empty/not empty status. For example, each time I run a report, I will get an unpredictable amount of returned records that will fill out rows in column A, however, since I want to extract strings from those returned records into different Columns, I have to enter formulas for each iteration within the next three columns (B, C, and D). Is there a way to insert a line that will evaluate the number of rows in Column A that are not blank, and then fill out the formulas in Columns B, C, and D to that final row? (I know that tables will do this automatically once information is entered in the first row, but for logistical reasons, I cannot use tables).
My current code that fills out the formula in Column B, Row 2 is:
Range("B2").Select
ActiveCell.FormulaR1C1 = "=MID(RC[-1],FIND(""By:"",RC[-1])+3,22)"
Thanks!
The formula that you actually need is
=IF(A2="","",MID(A2,FIND("By:",A2)+3,22))
instead of
=MID(A2,FIND("By:",A2)+3,22) '"=MID(RC[-1],FIND(""By:"",RC[-1])+3,22)"
This checks if there is anything in cell A and then act "accordingly"
Also Excel allows you to enter formula in a range in one go. So if you want the formula to go into cells say, A1:A10, then you can use this
Range("A1:A10").Formula = "=IF(A2="","",MID(A2,FIND("By:",A2)+3,22))"
Now how do we determine that 10? i.e the Last row. Simple
Sub Sample()
Dim ws As Worksheet
Dim lRow As Long
'~~> Change the name of the sheet as applicable
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
'~~> Find Last Row in Col A
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("B2:B" & lRow).Formula = "=IF(A2="""","""",MID(A2,FIND(""By:"",A2)+3,22))"
End With
End Sub
More About How To Find Last Row
You can use this to populate columns B:D based on Column A
Range("B2:D" & Range("A" & Rows.Count).End(xlUp).Row).Formula = _
"=MID($A2,FIND(""By:"",$A2)+3,22)"
I have a sheet with just order numbers and another with order numbers and all of the data associated with those order numbers. I want to match the order numbers and transfer all of the available data into the other sheet. I've been trying to use loops and VLOOKUP but I'm having problems (plus I have 116 columns I want to transfer data from so my vlookup expression doesn't look very nice). Any advice would be appreciated!
this is what I have so far and I'm getting an object error.
I don't think it's the right way to go about it in general though.
Dim LookUpRange As Range
Dim row As Range
Set LookUpRange = Worksheets("batches").Range("B4:B1384")
Set row = Worksheets("batches").Range("C:DL")
For Each row In LookUpRange
row.Select
Selection.FormulaArray ="=VLOOKUP(RC[-1],OrderLvl!RC[-1]:R[1380]C[113],{2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,207,108,109,110,111,112,113,114,115},FALSE)"
Next row
End Sub
Please consider this VBA script to resolve your inquiry:
Sub LookupOuput()
Dim OrderNumberColumn As Range
Set OrderNumberColumn = Worksheets("batches").Range("B2:B1384")
Dim LookUpRange As Range
Set LookUpRange = Worksheets("OrderLvl").Range("C:DL")
Dim cell As Range
Dim FindResult As Range
For Each cell In OrderNumberColumn
If Not cell.Value2 = Empty Then
Set FindResult = LookUpRange.Find(what:=cell.Value2)
If Not FindResult Is Nothing Then
cell.Range("A1:DJ1").Value2 = LookUpRange.Rows(FindResult.row).Value2
End If
End If
Next cell
End Sub
Basically searches for each Order Number in the first sheet on the second sheet. This outputs (if search term exists) the cell that that string is found which we later refer to its row number to output the whole row to the first sheet. Cheers,
A regular VLOOKUP may be able to give you what you need, if you use a small trick...
Insert a row above the data table, and put sequential numbers in
each cell of that row. (ie, A1 = 1, B1 = 2, C1 = 3, etc...)
Do the same thing on your blank table.
Assuming that your first order number is in cell A2, put the following formula into B2: =VLOOKUP($A2,[other sheet name]!$A$1:$DZ$5000,B$1,0)
Drag this formula across all 116 columns, then down all however many rows you've got.
You'll need to adjust the ranges, obviously, but make sure that your lookup array starts in column A. (or alternatively, that your numbers start in the same column as the first column in your array.) Adding the numbers along the top allows you to change what column of the array you're referencing, just by dragging the cell formula.