VBA copy values between 2 workbooks where X and X match? - excel

I have two workboks, one called slave and one called master.
Slave.xlsm
ID Case Size Names
1 1o Michael
2 4 Katie
3 3 Elliot
Master.xlsm
ID Case Size Names
1 1o
2 4
3 3
From Slave workbook, I am trying to copy the values from Name column where the ID and Case Size matches in Master.
I'm new to VBA and so have tried to compile my own code below with the help of some examples online. Here's what i've got so far:
Sub GetTheName()
Dim s As String, FileName As String
s = "C:\Users\******\Documents\*.xlsm"
FileName = Dir(s)
Do Until FileName = ""
If FileName Like "Slave*" Then MsgBox FileName
Dim w1 As Worksheet, w2 As Worksheet
Dim c As Range, FR As Long
Application.ScreenUpdating = False
Set w1 = Workbooks.Open(FileName).Sheets(1)
Set w2 = ThisWorkbook.Sheets(1)
For Each c In w1.Range("C10", w1.Range("C" & Rows.Count).End(xlUp))
FR = 0
On Error Resume Next
FR = Application.Match(c, w2.Columns("A"), 0)
On Error GoTo 0
If FR <> 0 Then w2.Range("R" & FR).Value = c.Offset(, 0)
Next c
Application.ScreenUpdating = True
FileName = Dir()
ActiveSheet.Range("A8").Value = Now()
Loop
End Sub
If i remove On Error Resume Next i get a type mismatch error on the below line:
FR = Application.Match(c, w2.Columns("R"), 0)
The code opens the workbok but does not copy anything across. I'm not sure why nothing is being copied. Please can someone show me where i am going wrong? Thanks

I have managed to get what you want... I'm not sure if you will be interested in my answer, but it does what you want...
First add a column where you concatenate A and B columns in the slave page
Find the matches with INDEX - MATCH method
I added the concatenate column on the D column... so the formula would be like this...
=INDEX(SLAVE!C2:C4;MATCH(CONCATENATE(MASTER!A2;MASTER!B2);SLAVE!D2:D4;0))
And this is the VBA code
Sub GetNames()
'
' GetNames Macro
'
'
LastRow = Sheets("SLAVE").Cells(Rows.Count, 1).End(xlUp).Row
Sheets("SLAVE").Activate
Sheets("SLAVE").Range("D2").FormulaR1C1 = "=CONCATENATE(RC[-3],RC[-2])"
Sheets("SLAVE").Range("D2").AutoFill Destination:=Range("D2:D" & LastRow & ""), Type:=xlFillDefault
LastRow = Sheets("MASTER").Cells(Rows.Count, 1).End(xlUp).Row
Sheets("MASTER").Activate
Sheets("MASTER").Range("C2").FormulaR1C1 = _
"=INDEX(SLAVE!RC:R[2]C,MATCH(CONCATENATE(MASTER!RC[-2],MASTER!RC[-1]),SLAVE!RC[1]:R[2]C[1],0))"
Sheets("MASTER").Range("C2").AutoFill Destination:=Range("C2:C" & LastRow & ""), Type:=xlFillDefault
End Sub

Based on the type mismatch in your comment, I will point you to here:
Application.Match gives type mismatch
It's likely you're not fining a match in the specified range.

you could use AutoFilter():
Option Explicit
Sub main()
Dim cell As Range, masterRng As Range
With Sheets("Master") '<--| reference your "Master" sheet
Set masterRng = .Range("A2", .Cells(.Rows.count, 1).End(xlUp)) '<--| reference its columns A cells from row 2 down to last not empty row
End With
With Sheets("Slave") '<--| reference your "Slave" sheet
With .Range("B1", .Cells(.Rows.count, 1).End(xlUp)) '<--| reference its columns A and B from row 1 (headers) down to column A last not empty row
For Each cell In masterRng '<--| loop through "Master" sheet column A ID Size"
.AutoFilter field:=1, Criteria1:=cell.Value '<--| filter it on its 2nd column (i.e. column B) with current cell offset 1 column value (i.e. current "Master" sheet "Case Size")
.AutoFilter field:=2, Criteria1:=cell.Offset(, 1).Value '<--| filter it on its 2nd column (i.e. column B) with current cell offset 1 column value (i.e. current "Master" sheet "Case Size")
If Application.WorksheetFunction.Subtotal(103, .Resize(, 1)) > 1 Then '<--| if any cell filtered other than headers
cell.Offset(, 2) = .Resize(.Rows.count - 1, 1).Offset(1, 2).SpecialCells(xlCellTypeVisible).Cells(1, 1) '<--|write first filtered 3rd column cell value in current cell offset 2 columns value (i.e. current "Master" sheet "Names")
End If
Next cell
End With
.AutoFilterMode = False
End With
End Sub

Related

Copy cells from one sheet and paste in another to a variable cell

I copy cells (from sheet1) if they contain a specific value (got this part figured out).
I need to paste them in a cell on sheet2 in row j.
Sheet1 has a long list of names, companies, emails, phones etc. with each person's information separated by a space. For Ex:
Column A Column B
Smith, Jill #N/A
CEO #N/A
ABC Corp 123 street ABC Corp
jill#ABC.com #N/A
#N/A
Smith, John #N/A
CTO #N/A
123 Inc ABC street 123 Inc
john#123.com #N/A
I have a variable (j) that counts each space and then if Cell b does not equal #NA, then cell a is copied and pasted into sheet2 column M and row j.
Variable j is needed because the formula in column B isn't 100% and the data is inconsistent so I need j so that the company name stays on the same line as the name. I need this because I have other code to split column A (like 4000 rows) into separate sheets by names, titles, companies, emails.
I.e. Sheet3 would have:
1. Jill Smith
2. John Smith
Sub AutoCompany()
Application.ScreenUpdating = False
Dim lr As Long, tr As Long, i As Long, j As Long, k As Long
Worksheets("Sheet1").Activate
lr = Range("A" & Rows.Count).End(xlUp).Row
tr = Worksheets("Sheet2").Range("A" & Rows.Count).End(xlUp).Row - 1
'this is my formula for column B
Range("B2:B" & lr).Formula = "=INDEX(CompaniesTbl[CompanyNamesList],IF(SUMPRODUCT(--ISNUMBER(SEARCH(CompaniesTbl[CompanyNamesList],A2)))<>0,SUMPRODUCT(--ISNUMBER(SEARCH(CompaniesTbl[CompanyNamesList],A2))*ROW($1:$" & tr & ")),NA()))"
j = 0
k = 1
For i = 2 To lr Step 1
'increase j by 1 if there is a blank space (to figure out where to paste)
If Cells(i, 1) = "" Then
j = j + 1
'extra variable just cause
k = k + 1
End If
'check for an actual value
If Application.IsNA(Cells(i, 2)) Then
Else
Worksheets("Sheet1").Cells(i, 2).Select
Selection.Copy
Worksheets("Company").Activate
Worksheets("Company").Range("M" & j).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Worksheets("Sheet1").Activate
End If
Next
Application.ScreenUpdating = True
End Sub
This causes an error
"object defined or variable defined"
If I remove j from my paste selection, the error is gone but all my pastes are overwritten.
I can't remember what I had done before, but I basically didn't have all of the sheet activations and that caused a out of range error. Which I fix by activating a sheet, but that causes my variable to cause an error.
Edit:
Based on the comments and answer, the issue is not in how the VBA is written per se. I think it has to do with the fact that the variable j is unable to be called in the if statement. I can't figure another way to do this or how to troubleshoot that issue.
From deciphering your code I assume that you what to copy the company names from column B to Worksheets("Company") column M, starting on the first row.
Dim cel As Range, j As Long 'assign your variables
With ThisWorkbook.Sheets("Sheet1") 'use "With" so you don't have to activate your worksheets
j = 1
For Each cel In .Range("B2:B" & .Cells(.Rows.Count, "B").End(xlUp).Row) 'loop through each cell in range
If Application.IsNA(cel) Then 'test for error and skip
ElseIf cel.Value = "" Then 'test for blank cell and skip
'It is better to set a cells value equal to another cells value then using copy/paste.
Else: ThisWorkbook.Sheets("Company").Cells(j, "M").Value = cel.Value
j = j + 1 'add 1 to j to paste on the next row
End If
Next cel
End With
Check my code's comments and adjust it to fit your needs
Option Explicit ' -> Always use this at the top of your modules and classes
' Define your procedures as public or private
' Indent your code (I use RubberDuck (http://rubberduckvba.com/) which is a great piece of software!
Public Sub AutoCompany()
On Error GoTo CleanFail
Application.ScreenUpdating = False ' This should be used with an error handler see https://rubberduckvba.wordpress.com/tag/error-handling/
' Declare object variables
Dim sourceSheet As Worksheet
Dim lookupSheet As Worksheet
Dim resultsSheet As Worksheet
Dim sourceRange As Range
Dim evalCell As Range
' Declare other variables
Dim sourceSheetName As String
Dim lookupSheetName As String
Dim resultsSheetName As String
Dim sourceLastRow As Long
Dim lookupLastRow As Long
' Initialize variables
sourceSheetName = "Sheet1"
lookupSheetName = "Sheet2"
resultsSheetName = "Company"
' Initialize objects
Set sourceSheet = ThisWorkbook.Worksheets(sourceSheetName) ' This could be replaced by using the sheet's codename see https://www.spreadsheet1.com/vba-codenames.html
Set lookupSheet = ThisWorkbook.Worksheets(lookupSheetName) ' Same as previous comment
Set resultsSheet = ThisWorkbook.Worksheets(resultsSheetName) ' Same as previous comment
' Worksheets("Sheet1").Activate -> Not needed
sourceLastRow = sourceSheet.Range("A" & Rows.Count).End(xlUp).Row ' This is unreliable -> see https://stackoverflow.com/a/49971492/1521579
lookupLastRow = lookupSheet.Range("A" & Rows.Count).End(xlUp).Row - 1 ' Couldn't understand why you subtract 1
' Define the sourceRange so we can loop through the cells
Set sourceRange = sourceSheet.Range("A2:A" & sourceLastRow)
' this is my formula for column B -> Comments should tell why you do something not what you're doing
sourceSheet.Range("B2:B" & sourceLastRow).Formula = "=INDEX(CompaniesTbl[CompanyNamesList],IF(SUMPRODUCT(--ISNUMBER(SEARCH(CompaniesTbl[CompanyNamesList],A2)))<>0,SUMPRODUCT(--ISNUMBER(SEARCH(CompaniesTbl[CompanyNamesList],A2))*ROW($1:$" & lookupLastRow & ")),NA()))"
' Begin the loop to search for matching results
For Each evalCell In sourceRange
' Skip cells that are empty
If evalCell.Value <> vbNullString Then
' Check value in column B (offset = 1 refers to one column after current cell and using not before application.IsNA checks for is found)
If Not Application.WorksheetFunction.IsNA(evalCell.Offset(rowOffset:=0, ColumnOffset:=1).Value) Then
' We use current evaluated cell row in the results sheet
resultsSheet.Range("M" & evalCell.Row).Value = evalCell.Value
End If
End If
Next evalCell
CleanExit:
Application.ScreenUpdating = True
Exit Sub
CleanFail:
Debug.Print "Catched an err: " & Err.Description & " ... do something!"
Resume CleanExit
End Sub
Let me know if it works and remember to mark the answer if it does
Thanks to everyone that tried helping. I found the problem.
My J variable was set to 0 and so the first time the code ran, it tried pasting to cell 0 which is out of scope of the worksheet. The reason why I had set my variable to 0 was because I assumed the first empty row that it finds (above the dataset) would set the variable to 1 but that was not the case.
Anyways, I set J to 1 and it worked...
D'oh

Match function in excel macro giving only first result

i'm new to excal macros/vba, and i am encountering a problem which i do not know how to approach.
I have a workbook that includes several sheets. There is 1 file which is more or less a master list, and 3 files which are sort of a packing list.
I have put in a command button with a macro in the 3 packing list respectively that tells me if a certain item in the packing list exist in the master, and if it does it tells me which row it appears in. This is working fine, however my problem is that if a particular items appears several times in the master list(due to different purchase date), the macro only gives the first result.
I would like to know if there are any ways such that all possible results appears instead of just the first.
below is a sample of the code i used
Private Sub CommandButton1_Click()
Dim k As Integer
For k = 3 To 1000
Cells(k, 24).Value = Application.Match(Cells(k, 2), Sheets("master").Range("B2:B1000"), 0)
Next k
End Sub
if your "master" sheet data is a list of contiguous not empty cells from B2 down to last not empty one, then here's a different approach playing around a bit with
Option Explicit
Private Sub CommandButton1_Click()
Dim cell As Range
With Worksheets("master") ' reference your "master" sheet
With .Range("B2", .Cells(.Rows.Count, "B").End(xlUp)) ' reference referenced sheet column B range from row 2 down to last not empty one
For Each cell In Range("B3", Cells(Rows.Count, "B").End(xlUp)) ' loop through packinglist sheet (i.e. where button resides) column B cells from row 3 down to last not empty one
If Not .Find(what:=cell.Value2, LookIn:=xlValues, lookat:=xlWhole) Is Nothing Then ' if current packinglist item is in "master"
.Replace what:=cell.Value2, replacement:=vbNullString, lookat:=xlWhole ' temporarily replace master item with a blank
cell.Offset(, 22).Value2 = Replace(.SpecialCells(xlCellTypeBlanks).Address(False, False), "B", "") ' write master list blanks rows in packinglist sheet current item row and column "X"
.SpecialCells(xlCellTypeBlanks).Value = cell.Value2 ' restore master list current packinglist item value
End If
Next
End With
End With
End Sub
I would use a dictionary to store every item in the master sheet, and everytime you find it duplicate, add another number with its row like this:
Option Explicit
Private Sub CommandButton1_Click()
Dim MasterKeys As Object
MasterKeys = FillDictionary(MasterKeys)
With ThisWorkbook.Sheets("MySheet") 'change MySheet for your actual sheet name
Dim arr As Variant
arr = .UsedRange.Value 'drop your data inside an array
Dim i As Long
For i = 3 To UBound(arr) 'loop through all the rows in your data
If MasterKeys.Exists(arr(i, 2)) Then arr(i, 24) = MasterKeys(arr(i, 2))
Next i
.UsedRange.Value = arr 'drop back your data
End With
End Sub
Function FillDictionary(MasterKeys As Object) As Object
Set MasterKeys = CreateObject("Scripting.Dictionary")
With Workbooks("MasterWorkbook.xlsx").Sheets("master") 'change MasterWorkbook for the actual filename of your master workbook
Dim LastRow As Long
LastRow = .Cells(.Rows.Count, 2).End(xlUp).Row 'find the last row on column B
Dim C As Range
For Each C In .Range("B2:B" & LastRow) 'loop through the range
If Not MasterKeys.Exists(C.Value) Then
MasterKeys.Add C.Value, C.Row
Else
MasterKeys(C.Value) = MasterKeys(C.Value) & "," & C.Row
End If
Next C
End With
End Function

How to find the differences in column A in 4 different worksheets

I have column K in "filter" sheets that need to be compare with column A in "Active_Buy", "Active_Others" and "Active_Make" sheets accordingly.
First it need to be compare with active_buy sheets. if there is value that in column K (filter sheet) but not in column A (active_Buy sheet), then it need to hold that value and compare it with column A (active_others sheets). If also didnt match, it need to compared with column A (Active_Make sheets).
So, if there is no any match, then the value need to be paste in new sheets name (Unmatched Part No).
I already search everywhere but only can find code that can only compare 2 worksheets only but not more than that.
'Below is the code that i found but only compared two worksheets only
' the concept just same like this but need to hold unmatch value and compare to next worksheet and so on.
Sub compare()
Sheets(3).Activate 'Go to sheet 3
Cells.Clear 'and clear all previous results
Range("a1").Select 'set cursor at the top
Sheets(1).Activate 'go to sheet 1
Range("a1").Select 'begin at the top
Dim search_for As String 'temp variable to hold what we need to look for
Dim cnt As Integer 'optional counter to find out how many rows we found
Do While ActiveCell.Value <> "" 'repeat the follwoing loop until it reaches a blank row
search_for = ActiveCell.Offset(0, 1).Value 'get a hold of the value in column B
Sheets(2).Activate 'go to sheet(2)
On Error Resume Next 'incase what we search for is not found, no errors will stop the macro
Range("b:b").Find(search_for).Select 'find the value in column B of sheet 2
If Err <> 0 Then 'If the value was not found, Err will not be zero
On Error GoTo 0 'clearing the error code
Sheets(1).Activate 'go back to sheet 1
r = ActiveCell.Row 'get a hold of current row index
Range(r & ":" & r).Select 'select the whole row
cnt = cnt + 1 'increment the counter
Selection.Copy 'copy current selection
Sheets(3).Activate 'go to sheet 3
ActiveCell.PasteSpecial xlPasteAll 'Past the entire row to sheet 3
ActiveCell.Offset(1, 0).Select 'go down one row to prepare for next row.
End If
Sheets(1).Activate 'return to sheet 1
ActiveCell.Offset(1, 0).Select 'go to the next row
Loop 'repeat
Sheets(3).Activate 'go to sheet 3 to examine findings
MsgBox "I have found " & cnt & " rows that did not exist in sheet 2"
End Sub
I'd use a For Each loop to run through the values on the 'Filter' sheet, set ranges on each of the other sheets, then check in each of the ranges. I've tested this code and it seems to do the trick. I've commented so you can see what's going on at each line.
(You'll need to adjust the sheet names to match you own, and adjust Application settings to make things run faster if you've got a lot of data.)
Sub compareColumns()
Dim lastRow1, lastRowAB, lastRowAO, lastRowAM, lastRowUMPN As Long
Dim rng1, rngAB, rngAO, rngAM As Range
Dim cell As Range
Dim found As Range
' Define our last rows for each sheet
lastRow1 = ThisWorkbook.Worksheets("FilterSheet").Range("K" & Rows.Count).End(xlUp).Row
lastRowAB = ThisWorkbook.Worksheets("ActiveBuy").Range("A" & Rows.Count).End(xlUp).Row
lastRowAO = ThisWorkbook.Worksheets("ActiveOthers").Range("A" & Rows.Count).End(xlUp).Row
lastRowAM = ThisWorkbook.Worksheets("ActiveMake").Range("A" & Rows.Count).End(xlUp).Row
lastRowUMPN = ThisWorkbook.Worksheets("UnmatchedPartNo").Range("A" & Rows.Count).End(xlUp).Row
' Set the ranges that we'll loop through
Set rng1 = ThisWorkbook.Worksheets("FilterSheet").Range("K1:K" & lastRow1)
Set rngAB = ThisWorkbook.Worksheets("ActiveBuy").Range("A1:A" & lastRowAB)
Set rngAO = ThisWorkbook.Worksheets("ActiveOthers").Range("A1:A" & lastRowAO)
Set rngAM = ThisWorkbook.Worksheets("ActiveMake").Range("A1:A" & lastRowAM)
' Loop through each cell in the filtered sheet
For Each cell In rng1
' Try to find the value in ActiveBuy sheet
Set found = rngAB.Find(cell.Value)
' If not found, try the next sheet
If found Is Nothing Then
Set found = rngAO.Find(cell.Value)
' If not found, try the next sheet
If found Is Nothing Then
Set found = rngAM.Find(cell.Value)
' If still not found, copy to the value to the 'Unmatched Parts' sheet
If found Is Nothing Then
ThisWorkbook.Worksheets("UnmatchedPartNo").Range("A" & lastRowUMPN + 1).Value = cell.Value
MsgBox "I have found a value " & cell.Value & " that did not exist in any sheets."
End If
End If
End If
' Reset 'found' to equal nothing for the next loop
Set found = Nothing
Next
End Sub
Here's a sub that takes 2 parameters;
A cell that has the value to search for, and a number indicating the sheet to search in.
When the sub doesn't find the value in neither of the sheets, it adds a new sheet "Unmatched Part No" if it doesn't exist and adds the value that's not found in column A in that sheet:
Sub searchSheet(ByVal searchFor As Range, sheetNum As Integer)
Dim sheetsArr As Variant
sheetsArr = Array("Active_Buy", "Active_Others", "Active_Make", "Unmatched Part No") 'You can change the names of your sheets here
If sheetNum = 3 Then 'When we reach the last sheet in our array, then we haven't find a match in neither of the previous sheets
Dim ws As Worksheet, wsExist As Boolean, lastRow As Integer
wsExist = False
'Check if the sheet "Unmatched Part No" exists
For Each ws In Worksheets
If ws.Name = sheetsArr(3) Then
wsExist = True
Exit For
End If
Next ws
'If the sheet "Unmatched Part No" doesn't exist add one with this name
If Not (wsExist) Then ThisWorkbook.Sheets.Add(after:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)).Name = sheetsArr(3)
lastRow = ThisWorkbook.Sheets(sheetsArr(3)).Cells(Rows.Count, "A").End(xlUp).Row 'last used row in column A in the unmatched sheet
ThisWorkbook.Sheets(sheetsArr(3)).Range("A" & lastRow + 1).Value2 = searchFor.Value2 'append the unfound value in column A
'MsgBox "New value" & searchFor.Value2 & "appended to 'Unmatched Part No' A" & lastRow + 1
Exit Sub
End If
Dim search 'Search should be of a variant type to accept errors given by the match function
search = Application.Match(searchFor.Value2, ThisWorkbook.Sheets(sheetsArr(sheetNum)).Range("A:A"), 0)
If IsError(search) Then searchSheet searchFor, sheetNum + 1 'When match doesn't find the searchFor value, Search is an #N/A error, then search in the next sheet
End Sub
And you need another sub to call the first one passing each cell of column K of filter sheet to the first sub. Here it is:
Sub lookInSheets()
Dim lastRw As Integer, ctrlCol As Range
lastRw = ThisWorkbook.Sheets("filter").Cells(Rows.Count, "K").End(xlUp).Row 'To abbreviate the search to just the filled cells in column K
Set ctrlCol = ThisWorkbook.Sheets("filter").Range("K1:K" & lastRw)
For Each ctrlCell In ctrlCol
searchSheet ctrlCell, 0
Next ctrlCell
End Sub
Copy both subs in a new module and run the second one to achieve your goal.

How to copy all rows that have specific values in multiple columns excel?

I am trying to copy all rows from an excel sheet Sheet1 that have a specific value in column A and B. and then paste them into a new sheet Sheet2. My specific example is I have figured out that I want to copy the rows that have a 0 in Column A as well as 4000 in Column B.
The problem that I am having is that the code copies all rows that have a 0 in column A not just the ones that meet both conditions.
My code is below for reference:
Sub Temp_copy()
set i = Sheets("Sheet1")
set e = Sheets("Sheet2")
Dim d
Dim j
d = 1
j = 2
Do Until IsEmpty(i.Range("A" & j))
If i.Range("A"&j) = Range("B6"&j) And i.Range("B" & j) = Range(B"10"&j) Then
d=d+1
e.Rows(d).Value=i.Rows(j).Value
End If
j = j+1
Loop
End Sub
Hopefully that makes sense. I am new to VBA so any help or guidance to achieve what I need would be muchly appreciated.
you can use AutoFilter() method of Range object, as follows (explanations in comments):
Sub foo()
Dim wsResult As Worksheet
Set wsResult = Sheets("Sheet02")
With Worksheets("Sheet01")
With .Range("A2:B" & .Cells(.Rows.Count, "A").End(xlUp).Row) 'reference its columns A:B cells from row 2 (header) down to last not empty one in column "A" (If you need to copy more columns than simply adjust "A2:B" to whatever columns range you need)
.AutoFilter field:=1, Criteria1:="0" ' filter referenced cells on 1st column with "0" content
.AutoFilter field:=2, Criteria1:="4000" ' filter referenced cells on 2nd column with "4000" content
If Application.WorksheetFunction.Subtotal(103, .Columns(1)) > 1 Then .Offset(1).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible).Copy Destination:=wsResult.Range("A1") ' if any filtered cell other than the header then copy their first five columns and paste to 'wsResult' sheet starting from its column A last not empty cell
End With
.AutoFilterMode = False
End With
End Sub
Try this:
Sub Temp_Copy()
Dim cl As Range, rw As Integer
rw = 1
For Each cl In Worksheets("Sheet1").Range("A1:A10") //Set range as needed
If cl = 0 And cl.Offset(0, 1) = 4000 Then
cl.EntireRow.Copy Destination:=Worksheets("Sheet2").Range("A" & rw)
rw = rw + 1
End If
Next cl
End Sub

VBA: find file and copy cell values from column in one workbook to another based on condition?

I have a spreadsheet like so called slave:
Id Delivery Date Case Size Receivings Allocated
1 12/12/2016 4 100 100
2 13/12/2016 5 200 50
3 11/10/2016 6 200 25
4 15/11/2014 3 90 10
I also have another spreadsheet exactly the same but called master.
Id Delivery Date Case Size Receivings Allocated
1 12/12/2016 4
2 13/12/2016 5
3 11/10/2016 6
4 15/11/2014 3
I am trying to copy to receivings and the allocated units from the slave workbook over to the master workbook where the ID, Delivery Date and Case Size matches.
Here's what i've tried so far:
Sub GetTheName()
Dim s As String, FileName As String
s = "C:\Users\Mark O'Brien\Documents\*.xlsm"
FileName = Dir(s)
Do Until FileName = ""
If FileName Like "Food Specials Rolling Depot Memo*" Then MsgBox FileName
'Start Merge of Memo
Dim Dic As Object, key As Variant, oCell As Range, i&
Dim w1 As Worksheet, w2 As Worksheet
Set Dic = CreateObject("Scripting.Dictionary")
Set w1 = Workbooks.Open(FileName).Sheets(1)
Set w2 = ThisWorkbook.Sheets(1)
i = w1.Cells.SpecialCells(xlCellTypeLastCell).Row
For Each oCell In w1.Range("R10:R" & i)
If Not Dic.exists(oCell.Value) Then
Dic.Add oCell.Value, oCell.Offset(, -3).Value
End If
Next
i = w2.Cells.SpecialCells(xlCellTypeLastCell).Row
For Each oCell In w2.Range("F10:F" & i)
For Each key In Dic
If oCell.Value = key Then
oCell.Offset(, 2).Value = Dic(key)
End If
Next
Next
'End Merge of Memo
FileName = Dir()
ActiveSheet.Range("A8").Value = Now()
Loop
End Sub
Nothing seems to happen apart from the workook opening. Nothing is copied over and no error is given. Please can someone show me where i am going wrong? Thanks
you could use AutoFilter() method, like follows:
Option Explicit
Sub main()
Dim cell As Range, masterRng As Range
With Sheets("MasterSheet") '<--| reference your "Master" sheet (change "MasterSheet" to your actual "Master" sheet name)
Set masterRng = .Range("A2", .Cells(.Rows.count, 1).End(xlUp)) '<--| reference its columns A cells from row 2 down to last not empty row
End With
With Sheets("SlaveSheet") '<--| reference your "Slave" sheet (change "SlaveSheet" to your actual "Slave" sheet name)
With .Range("C1", .Cells(.Rows.count, 1).End(xlUp)) '<--| reference its columns A and B range from row 1 (headers) down to column A last not empty row
For Each cell In masterRng '<--| loop through "Master" sheet column A "ID"
.AutoFilter field:=1, Criteria1:=cell.Value '<--| filter referenced range on its 2nd column (i.e. column B) with current cell 1 column offset value (i.e. current "Master" sheet "ID")
.AutoFilter field:=3, Criteria1:=cell.Offset(, 2).Value '<--| filter referenced range on its 3rd column (i.e. column C) with current cell 2 columns offset value (i.e. current "Master" sheet "Case Size")
If Application.WorksheetFunction.Subtotal(103, .Resize(, 1)) > 1 Then '<--| if any cell filtered other than headers
cell.Offset(, 3).Resize(, 2).Value = .Resize(.Rows.count - 1, 1).Offset(1, 3).SpecialCells(xlCellTypeVisible).Cells(1, 1).Resize(, 2).Value '<--|write first filtered 3rd column cell value in current cell offset 2 columns value (i.e. current "Master" sheet "Names")
End If
Next cell
End With
.AutoFilterMode = False
End With
End Sub

Resources