Find a sheet based on a cell name, then find the entry based on a different cell name, and fill in the values from adjacent cells - vba

I'm pretty new to VBA, I've got a spread sheet that has a list of vehicle ID's in a row of columns, and different identifiers (ID) in column A.
So far I'm able to search for the sheet with the vehicle name and copy a range of cells to the main sheet. I'm trying to make it so that once it finds the specific vehicle sheet, it looks for the specific ID and pulls that in, rather than copy a set range of cells. I'm having it return nothing now, and when I had it before excel would crash, so I assumed I was in some sort of endless loop.
Dim ws As Worksheet, sh As Worksheet
Dim Rng As Range, c As Range
Dim ECU_Ovv As Range, ECU_V As Range
Set ws = Sheets("Overview") 'main worksheet to copy everything to
Set Rng = ws.Cells(3, 3).Resize(3, LastColumn) ' I;ve calculated LastColumn earlier, it's defined as a Long
Set ECU_Ovv = ws.Cells(5, 2).Resize(LastRow, 2)
For Each sh In Sheets
For Each c In Rng.Cells
If sh.Name = c Then
'Find row range for specific vehicle
LastRow = sh.Cells(Rows.Count, 2).End(xlUp).Row
Set ECU_V = sh.Cells(5, 2).Resize(LastRow, 2) ' this is the only syntax I could figure out to get it to let me set a range with a calculated variable
For Each ECU_Ovv In ECU_V.Cells 'now look for the ID in the specific sheet
If ECU_Ovv.Cells = ECU_V.Cells Then
a = ECU_Ovv.Value 'Put this here to see if I am able to match ID's from the main sheet to the specific sheet
'sh.Range("D12:D47").Copy Destination:=ws.Cells(24, c.Column) 'this was working but it's hardcoded so any change in the sheets would break it
End If
Next ECU_Ovv
End If
Next c
Next sh
I'm planning on adding a copy cell, 2 columns over (from the found ID) to the column of the vehicle (Rng), but I'll cross that bridge when I get there!

Related

Trying to identify matching cells randomly distributed in 2 seperate Excel sheets, and have the matching data copied and pasted into a third sheet

So I have several worksheets on the same Excel workbook that I need to compare. Worksheet 1 is the masterlist, and I need to compare worksheets 1-2, 1-3, 1-4. I then need to paste any similar 1-2 data cells in column A of worksheet 5, and similar 1-3 data cells in column B of worksheet 5, and 1-4 similarities to column C of worksheet 5. For starters I have focused on getting the 1-2 comparison to work. So far I have been able to get my test number to be pasted to cell A1 of sheet 5. I am running into trouble because it only works for 1 cell, and I cannot get the program to paste a similarity in A1, and then A2... etc, when I have multiple similar items. They just overwrite each other in cell A1, or in the entire A column. I am also running into trouble because the program as it is written stops when it hits a blank space, but I need it to just skip the blanks and read the next cell when it comes across them. This is because my data sheets are very messy and the data is scattered over several thousands of rows among several different columns, with spaces randomly interjected. Below is my working code for just reading a similarity, and pasting it into A1. I should note that I have considered adding a specific cell range depending on which sheet I am on in order to put an end point on the program, but I haven't quite figured out how to work it in.
Sub findDuplicates()
' code to find duplicates in 2 different worksheets
Dim rng1, rng2, rngA, cell1, cell2 As Range
' 4 ranges have been defined
Set rng1 = Sheets("Sheet1").Range("C:C")
'rng1 defines the existing data in column C and worksheet1
Set rng2 = Sheets("Sheet2").Range("C:C")
'rng2 defines the data in column C and worksheet2
Set rngA = Sheets("Sheet5").Range("A1")
For Each cell1 In rng1
If IsEmpty(cell1.Value) Then Exit For
'check for empty rows. If true then exit the program
For Each cell2 In rng2
If IsEmpty(cell2.Value) Then Exit For
If cell1.Value = cell2.Value Then
'compare data in cell1 and cell2 and then copy/paste if they have equal values
cell1.Copy
Sheets("Sheet5").Select
rngA.Select
ActiveSheet.Paste
End If
'run the looping process
Next cell2
Next cell1
End Sub
The general idea of what I imagine the program to look like would be something like
Define ranges
Block of code that runs through each cell in sheet 1 comparing it to all cells in sheet 2.
Block of code that, when similarities are found, copy/paste that cell on sheet 1 to sheet 5 column A
*Program resumes scan from the next cell on sheet 1*
Block of code that breaks the program when it hits the end of the specified cell range
Any help with this would be greatly appreciated! You would be saving me at least a week's worth of mindless work.
A few comments about your code:
Dim rng1, rng2, rngA, cell1, cell2 As Range means only cell2 is defined As Range, while rng1, rng2, rngA, cell1 defined As Variant
You don't need to have 2 For loops to compare, you can replace the second For loop with the Match function, it will save you precious run-time.
You need to find the next empty row in "Sheet5", by using NextRow = Sheets("Sheet5").Cells(Sheets("Sheet5").Rows.Count, "A").End(xlUp).Row + 1
Last, you don't need to Select the sheets in order to copy>>paste, you can so it in 1-line (see in my code below).
Code
Sub findDuplicates()
' code to find duplicates in 2 different worksheets
' 4 ranges have been defined
Dim rng1 As Range, rng2 As Range, rngA As Range, cell1 As Range, cell2 As Range
Dim NextRow As Long
'rng1 defines the existing data in column C and "Sheet1"
Set rng1 = Sheets("Sheet1").Range("C:C")
'rng2 defines the data in column C and "Sheet2"
Set rng2 = Sheets("Sheet2").Range("C:C")
Set rngA = Sheets("Sheet5").Range("A1")
For Each cell1 In rng1
If Not IsEmpty(cell1.Value) Then ' only check non-empty cells
If Not IsError(Application.Match(cell1.Value, rng2 , 0)) Then ' <-- confirm match was asuccessful
' find next empty row in column "A" in "Sheet5"
NextRow = Sheets("Sheet5").Cells(Sheets("Sheet5").Rows.Count, "A").End(xlUp).Row + 1
' Copy >> Paste in 1 line (without need to Select the Sheets)
cell1.Copy Destination:=Sheets("Sheet5").Range("A" & NextRow)
End If
'run the looping process
End If
Next cell1
End Sub
Your problem is that rngA points to A1 and nothing changes that.
Add one line after your paste command:
ActiveSheet.Paste
Set rngA = rngA.Offset(1,0) ' This will move the pasting location one step down

updating column and row values of the list which has duplicate values

I have merged variable amount of worksheets which are called anything includes the word "data" through this code;
Dim masterSheet As Worksheet
Set masterSheet = Sheets("Komko")
'Variable to save the used Range of the master sheet
Dim usedRangeMaster As Integer
Dim ws As Worksheet
'loop through each worksheet in current workbook
For Each ws In Worksheets
'If sheetname contains "data" (UCase casts the Name to upper case letters)
If InStr(1, UCase(ws.Name), "DATA", vbTextCompare) > 0 Then
'calculate the used range of the master sheet
usedRangeMaster = masterSheet.UsedRange.SpecialCells(xlCellTypeLastCell).Row + 1
'Variable to save the used Range of the sub sheet
Dim usedRangeSub As Integer
'calculate the used range of the sub sheet
usedRangeSub = ws.UsedRange.SpecialCells(xlCellTypeLastCell).Row
'copy relevant range from the subsheet
ws.Range("C1:C" & usedRangeSub).Copy
'paste the copied range after the used range in column a
masterSheet.Range("A" & usedRangeMaster).PasteSpecial
End If
Next ws
This code copies the C column of the "data" including Sheets and then pastes it to my master Sheets( which is called "Komko") Column A. Now i would like identify the same values in Column C and delete the complete row of the previous matching value. (e.g if C1 has value "123" and if C7 has value "123" the whole row which includes C1 should automatically be deleted)
How can i do this ?
See http://analysistabs.com/vba/find-duplicate-values-column/ to find your duplicate entries and Delete a row in Excel VBA to get some ideas how to delete the row in a good way.
Start searching after you merged your column C. Use a Boolean variable to skip the first found entry if necessary. Replace the code Cells(iCntr, 2) = "Duplicate" from the first link and put your way of deleting the row there.

VBA compare 2 worksheets and extract entire work if there is a match in a column

I receive a monthly aging report. I need to compare these 2 reports to find out what items appear on each of the reports. I need a VBA to look at Column B of both sheets and if there is a match, extract those rows only. In addition, I need a vba to find out if something has changed. For those that are not familiar with aging report, this reports tells me how far the customer is past due in paying me. So if customer 1, was in the Aging 0-30 (Column S) on report pulled on 20151023, then on the report pulled 20160223, this customer should be in Aging 90-120 (Column V). I'm thinking the best way to display this information is to display matched data with no changes in the No Changes Sheet. Then, in the sheet called Changes, I would like to display about 6 columns of information: Report Date, Dealr, Contract Number, Status, Aging History, & AR Amount. The Aging History will tell me what bucket this customer was on when the report was pulled. This information will come from the column headings (S-X). The AR Amount will be the amount appearing in that column. I will try to upload a sample.
The following gives you a way to compare the same column in two sheets. The first way looks for a matching value anywhere in the second sheet's column, the second method only returns a match if the matching cells are on the same row in both sheets
Sub CompareSheets(sheet1 As Worksheet, sheet2 As Worksheet, columnNumber As Long)
Dim ws1 As Worksheet, ws2 As Worksheet
Dim ws1Data As Range, ws2Data As Range
Dim col As Long
Dim i As Integer
Dim cell1 As Range, cell2 As Range
Set ws1 = sheet1
Set ws2 = sheet2
col = columnNumber
ws1Data = ws1.Columns(col).Cells
ws2Data = ws2.Columns(col).Cells
Find a match anywhere in either column
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
' This code will find any match between the two sheets
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
'Checks each cell in the target column of sheet 1
For Each cell1 In ws1Data
'Checks each cell in the target column of sheet 2
For Each cell2 In ws2Data
'If the cell from sheet 1 matches any cell in sheet 2 then do stuff
If cell1 = cell2 Then
'Do stuff with the data here
End If
Next cell2
Next cell1
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Find a match only if the matching cells are on the same row
' ////////////////////////////////////////////////////////
' This code will find a match ONLY if both entries are
' on the same row in their respective sheets
' ////////////////////////////////////////////////////////
'Checks each cell in the target column of sheet 1
For Each cell1 In ws1Data
'Checks each cell in the target column of sheet 2
For Each cell2 In ws2Data
'If the cell from sheet 1 matches any cell in sheet 2
'AND there are on the same row in both sheets then do stuff
If (cell1 = cell2) And (cell1.Row = cell2.Row) Then
'Do stuff with the data here
End If
Next cell2
Next cell1
' /////////////////////////////////////////////////////////
' /////////////////////////////////////////////////////////
End Sub
Then you can make a button or macro that calls the sub
Call CompareSheets(firstworksheet, secondworksheet, 2) '2 is the column number for B
A proper example
Call CompareSheets(Worksheets(1), Worksheets(2), 2)
As for what you want to do with the matches once they're located, that's really for another post.

Is there a way to get the paste section of this code to cycle down one row at a time each time data is pasted?

My aim with this bit of code is to paste the contents of column D into a different Sheet if the contents in column N on the same row within the initial Sheet is = "REDUCE ONLY".
I'm struggling to find a way to paste all the entries into the second Sheet with no blank rows between them.
Currently I'm sorting the initial Sheet so all the REDUCE ONLY entries are in order at the top of the column N so they're ordered correctly in the output sheet but this isn't very robust if I get a different set of values to what's expected in column N. Is there a different way to phrase:
"cfdSht.Cells(c.Row - 1, 1).PasteSpecial Paste:=xlPasteValues"
So far I've got:
Dim c As Range
Dim rCheck As Range
Dim LRMAIN As Long
Dim cfdSht As Worksheet
Dim mainSht As Worksheet
Set mainSht = ThisWorkbook.Worksheets("Sheet1")
Set cfdSht = ThisWorkbook.Worksheets("ProductSettingNgCfd")
''Set Last Row
LRMAIN = mainSht.Range("A2").CurrentRegion.Rows.Count
''Set Range
Set rCheck = mainSht.Range("B2:N" & LRMAIN)
''Copy any value in column D where the value on the same row in column N is "REDUCE ONLY". Paste into second Sheet with starting point adjusted up 1 row.
For Each c In rCheck
If c.Value = "REDUCE ONLY" Then
mainSht.Cells(c.Row, 4).Copy
cfdSht.Cells(c.Row - 1, 1).PasteSpecial Paste:=xlPasteValues
End If
Next
Thanks
Replace this:
mainSht.Cells(c.Row, 4).Copy
cfdSht.Cells(c.Row - 1, 1)
With this
cfdSht.Cells(cfdSht.RowsCount, 1).End(xlUp).Offset(1).value = mainSht.Cells(c.Row, 4).Value
The first part will start at the bottom of the sheet then go up to the first occupied cell then move one down to the first unoccupied cell.
I used the direct assign method, because it is less taxing on the process than copy and paste. As you were looking only for values this will just put the value of the one cell into the other.

Create an Excel worksheet based on specific column values

I am enclosing a link with a sample spreadsheet.
What I would like to do is create multiple worksheets using the key column of "Facility", perhaps using a macro. For example, I would like to create a new worksheet called Houston and fill the worksheet with the data specific to that row. Some of the cells may end up in different locations in the new worksheet. I need to do a separate worksheet for every value in "Facility". The original that I am working on has 270 rows (270 facilities).
Does anyone have any idea how to do something like this? I am new to running and creating macros. I did create a macro that didn't work right.
Try this:
Dim wks As Worksheet
Dim lstRow As ListRow
For Each lstRow In ThisWorkbook.Worksheets("Sheet1").ListObjects("Table1").ListRows
Set wks = ThisWorkbook.Worksheets.Add
wks.Name = lstRow.Range.Cells(, 1).Value
With wks
.Range(.Cells(1, 1), .Cells(1, lstRow.Range.Columns.Count)) = lstRow.Range.Value
End With
Next
Set wks = Nothing
Assumptions:
Worksheet name where data resides is called Sheet1
Table containing data is a ListObject (e.g., convert your data range into an Excel table)
ListObject name is Table1