I wrote this code, but I'm having trouble getting it to work properly.Instead of seeing C2:D5 as a range of ten items, I'd like to see C2 and cell D2 as a single item, and so on. Instead of ten items, the list will essentially consist of five. This is then copied to the appropriate cells D3:E3, as shown below. Is that even possible with vba?
Dim wb As Workbook
Set wb = ThisWorkbook
Dim startsheet As Worksheet
Set startsheet = wb.Sheets("start")
Dim r As Range
Set r = startsheet.Range("C2:D5") '
Dim sh As Worksheet
For Each sh In Worksheets
For i = 1 To r.Count
If Not i + 1 > Worksheets.Count Then Worksheets(i + 1).Range("D3:E3").Value = r.Item(i,1).Value
Next i
Next sh
End Sub ```
The problem in your code was that you were using 2 loops when you only needed one. The loop for the sheets was unnecesary because you were already looping through sheets with the code "Worksheets(i + 1).Range("D3").Value"
Sub test()
Dim wb As Workbook
Set wb = ActiveWorkbook
Dim i As Long
Dim startsheet As Worksheet
Set startsheet = wb.Sheets("start")
Dim r As Range
Set r = startsheet.Range("C2:D5")
Dim sh As Worksheet
For i = 1 To r.Rows.Count
If Not i + 1 > wb.Worksheets.Count Then
Worksheets(i + 1).Range("D3").Value = r.Item(i, 1).Value
Worksheets(i + 1).Range("E3").Value = r.Item(i, 2).Value
Else
End If
Next i
End Sub
Yes, you can easily touch up the code to add sheets if you add more items to column C in startsheet. It'd be like this:
Sub TEST()
Dim wb As Workbook
Set wb = ActiveWorkbook
Dim i As Long, LastRow As Long
Dim startsheet As Worksheet
Set startsheet = wb.Sheets("start")
LastRow = startsheet.Range("C2:C" & Rows.Count).End(xlDown).Row
Dim r As Range
startsheet.Activate
Set r = startsheet.Range(Cells(2, 3), Cells(LastRow, 3))
Dim sh As Worksheet
For i = 1 To r.Rows.Count
If i + 1 > wb.Worksheets.Count Then
Set sh = wb.Sheets.Add(After:=wb.Worksheets(wb.Worksheets.Count))
Worksheets(i + 1).Range("D3").Value = r.Item(i, 1).Value
Worksheets(i + 1).Range("E3").Value = r.Item(i, 2).Value
Else
Worksheets(i + 1).Range("D3").Value = r.Item(i, 1).Value
Worksheets(i + 1).Range("E3").Value = r.Item(i, 2).Value
End If
Next i
End Sub
I will use copy method again, however I will assume the copy sheet is sheet1 and you already created sheet 2 -5 for the function, please try and see and modify for if statement in case you have other issue:
Sub test2()
Dim wb As Workbook
Dim i As Long
Set wb = ThisWorkbook
Dim startsheet As Worksheet
Set startsheet = wb.Sheets("start")
For i = 2 To ThisWorkbook.Worksheets.Count
startsheet.Range("C" & i, "D" & i).Copy Worksheets(i).Range("D3")
Next
End Sub
Copy Each Row to Each Next Worksheet
If you opt for using .worksheets(1) then remove the swsName constant.
Play with the values of the remaining three constants.
Sub CopyRowsForNext()
Const swsName As String = "start"
Const srgAddress As String = "C2:D5"
Const dFirst As String = "D3" ' First Destination Cell
Const wsFirst As Long = 2 ' First Destination Worksheet
Dim wb As Workbook: Set wb = ThisWorkbook
Dim wsCount As Long: wsCount = wb.Worksheets.Count
If wsCount = 0 Then Exit Sub
Dim sws As Worksheet: Set sws = wb.Worksheets(swsName)
' Maybe this would be more appropriate (forgetting about "start"):
'Dim sws As Worksheet: Set sws = wb.Worksheets(1)
Dim srg As Range: Set srg = sws.Range(srgAddress)
Dim srCount As Long: srCount = srg.Rows.Count
Dim scCount As Long: scCount = srg.Columns.Count
Dim cIndex As Long
Dim r As Long
For r = 1 To srCount
cIndex = r + wsFirst - 1
If cIndex <= wsCount Then
wb.Worksheets(cIndex) _
.Range(dFirst).Resize(, scCount).Value = srg.Rows(r).Value
End If
Next r
End Sub
Sub CopyRowsForEachNext()
Const swsName As String = "start"
Const srgAddress As String = "C2:D5"
Const dFirst As String = "D3" ' First Destination Cell
Const wsFirst As Long = 2 ' First Destination Worksheet
Dim wb As Workbook: Set wb = ThisWorkbook
Dim wsCount As Long: wsCount = wb.Worksheets.Count
If wsCount = 0 Then Exit Sub
Dim sws As Worksheet: Set sws = wb.Worksheets(swsName)
' Maybe this would be more appropriate (forgetting about "start"):
'Dim sws As Worksheet: Set sws = wb.Worksheets(1)
Dim srg As Range: Set srg = sws.Range(srgAddress)
Dim srCount As Long: srCount = srg.Rows.Count
Dim scCount As Long: scCount = srg.Columns.Count
Dim srrg As Range
Dim cIndex As Long
Dim n As Long
For Each srrg In srg.Rows
n = n + 1
cIndex = n + wsFirst - 1
If cIndex <= wsCount Then
wb.Worksheets(cIndex) _
.Range(dFirst).Resize(, scCount).Value = srrg.Value
End If
Next srrg
End Sub
Related
I use this VBA code which works very well. It searches in column A of an external Excel file for all the terms in column D, and replaces the matches, with the content of column B of the external file in the found row. So for instance:
if D5 matches A11 of the external file, then B11 from external file is written to D5.
I am now trying to modify it so that it still searches in column 4 for matches in column A of external file, but for any matches found, replaces the column E with column B of the external file. So:
If D5 matches A11, then B11 from external file is written to E5.
Well, I've tried many changes in the replace loop but it throws errors every time. I suppose I don't use the correct command!
Private Sub CommandButton1_Click()
Dim NameListWB As Workbook, thisWb As Workbook
Dim NameListWS As Worksheet, thisWs As Worksheet
Dim i As Long, lRow As Long
'This is the workbook from where code runs
Set thisWb = ThisWorkbook
Set thisWs = thisWb.Sheets("Sheet1")
'External file
Set NameListWB = Workbooks.Open("E:\Data.xlsx")
Set NameListWS = NameListWB.Worksheets("Sheet1")
With NameListWS
'Detect end row in Col A of Data.xlsx
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
'Loop though Column A
For i = 1 To lRow
'... and perform replace action
thisWs.Columns(4).Replace What:=.Range("A" & i).Value, _
Replacement:=.Range("B" & i).Value, _
SearchOrder:=xlByColumns, _
MatchCase:=False
Next i
End With
End Sub ```
Untested:
Private Sub CommandButton1_Click()
Dim NameListWB As Workbook
Dim NameListWS As Worksheet, thisWs As Worksheet, n As Long
Dim i As Long, arrList, arrD, rngD As Range
Set thisWs = ThisWorkbook.Sheets("Sheet1") 'This is the workbook from where code runs
'get an array from the column to be searched
Set rngD = thisWs.Range("D1:D" & thisWs.Cells(Rows.Count, "D").End(xlUp).Row)
arrD = rngD.Value
'Open external file and get the terms and replacements as an array
Set NameListWB = Workbooks.Open("E:\Data.xlsx")
With NameListWB.Worksheets("Sheet1")
arrList = .Range("A1:B" & .Cells(Rows.Count, "A").End(xlUp).Row).Value
End With
For n = 1 To UBound(arrD, 1) 'check each value from ColD
For i = 1 To UBound(arrList, 1) 'loop over the array of terms to search for
If arrD(n, 1) = arrList(i, 1) Then 'exact match ?
'If InStr(1, arrD(n, 1), arr(i, 1)) > 0 Then 'partial match ?
rngD.Cells(n).Offset(0, 1).Value = arrList(i, 2) 'populate value from ColB into ColE
Exit For 'got a match so stop searching
End If
Next i
Next n
End Sub
A VBA Lookup (Application.Match)
Adjust (play with) the values in the constants section.
Compact
Sub VBALookup()
' Source
Const sPath As String = "E:\Data.xlsx"
Const sName As String = "Sheet1"
Const slCol As String = "A" ' lookup
Const svCol As String = "B" ' value
Const sfRow As Long = 2
' Destination
Const dName As String = "Sheet1"
Const dlCol As String = "D" ' lookup
Const dvCol As String = "E" ' value
Const dfRow As Long = 2
Application.ScreenUpdating = False
' Source
Dim swb As Workbook: Set swb = Workbooks.Open(sPath)
Dim sws As Worksheet: Set sws = swb.Worksheets(sName)
Dim slRow As Long: slRow = sws.Cells(sws.Rows.Count, slCol).End(xlUp).Row
If slRow < sfRow Then Exit Sub ' no data in lookup column range
Dim srCount As Long: srCount = slRow - sfRow + 1
Dim slrg As Range: Set slrg = sws.Cells(sfRow, slCol).Resize(srCount)
Dim svData As Variant
With slrg.EntireRow.Columns(svCol)
If srCount = 1 Then ' one cell
ReDim svData(1 To 1, 1 To 1): svData(1, 1) = .Value
Else ' multiple cells
svData = .Value
End If
End With
' Destination
Dim dwb As Workbook: Set dwb = ThisWorkbook ' workbook containing this code
Dim dws As Worksheet: Set dws = dwb.Worksheets(dName)
Dim dlRow As Long: dlRow = dws.Cells(dws.Rows.Count, dlCol).End(xlUp).Row
If dlRow < dfRow Then Exit Sub ' no data in lookup column range
Dim drCount As Long: drCount = dlRow - dfRow + 1
Dim dlrg As Range: Set dlrg = dws.Cells(dfRow, dlCol).Resize(drCount)
Dim dData As Variant
If drCount = 1 Then ' one cell
ReDim dData(1 To 1, 1 To 1): dData(1, 1) = dlrg.Value
Else ' multiple cells
dData = dlrg.Value
End If
' Loop.
Dim srIndex As Variant
Dim dValue As Variant
Dim dr As Long
Dim MatchFound As Boolean
For dr = 1 To drCount
dValue = dData(dr, 1)
If Not IsError(dValue) Then
If Len(dValue) > 0 Then
srIndex = Application.Match(dValue, slrg, 0)
If IsNumeric(srIndex) Then MatchFound = True
End If
End If
If MatchFound Then
dData(dr, 1) = svData(srIndex, 1)
MatchFound = False
Else
dData(dr, 1) = Empty
End If
Next dr
' Close the source workbook.
swb.Close SaveChanges:=False
' Write result.
dlrg.EntireRow.Columns(dvCol).Value = dData
' Inform.
Application.ScreenUpdating = True
MsgBox "VBA lookup has finished.", vbInformation
End Sub
pls help, I need a excel vba code, which copies every second value of a row
and paste that into a column in another sheet
.
I tried it like this
Sub Test()
Worksheets("Sheet1").Activate
Dim x As Integer
For x = 5 To 196 Step 2
Worksheets("Tabelle1").Activate
Cells(x, 2).Value = Sheets("Sheets1").Range("E2:GN2")
Next x
End Sub
Sub test()
Dim WkSource As Worksheet
Dim WkDestiny As Worksheet
Dim i As Long
Dim j As Long
Dim LR As Long
Dim k As Long
Set WkSource = ThisWorkbook.Worksheets("Hoja1")
Set WkDestiny = ThisWorkbook.Worksheets("Hoja2")
With WkSource
LR = .Range("E" & .Rows.Count).End(xlUp).Row
k = 2 'starting row where you want to paste data in destiny sheet
For i = 2 To LR Step 1
For j = 5 To 12 Step 2 'j=5 to 12 because my data goes from column E to L (5 to 12)
WkDestiny.Range("D" & k).Value = .Cells(i, j).Value
k = k + 1
Next j
Next i
End With
Set WkSource = Nothing
Set WkDestiny = Nothing
End Sub
The code loop trough each row and each column (notice step 2 to skip columns)
Output I get:
you can start from something like this:
Option Explicit
Private Sub dataCp()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = wb.Sheets("Sheet1")
Dim ws2 As Worksheet: Set ws2 = wb.Sheets("Tabelle1")
Dim lrow As Long, lcol As Long, i As Long
Dim rng As Range, c As Range
lcol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
For i = 5 To lcol
lrow = (ws2.Cells(ws2.Rows.Count, "D").End(xlUp).Row) + 1
ws2.Range("D" & lrow).Value = ws.Cells(2, i).Value
i = i + 1
Next
End Sub
Transpose Data
It will transpose all rows of a range in a worksheet to consecutive columns on another worksheet.
Since scStep is 2, in this case, only every other cell in each source row will be copied.
Adjust (play with) the values in the constants section.
Option Explicit
Sub TransposeData()
' Source
Const sName As String = "Sheet1"
Const sFirstRowAddress As String = "E2:GN2"
Const scStep As Long = 2
' Destination
Const dName As String = "Tabelle1"
Const dFirstCellAddress As String = "D2"
' Both
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Write the values from the source range to the source array.
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim sData As Variant
Dim srCount As Long
With sws.Range(sFirstRowAddress)
' Populate data.
' With .Resize(20)
' .Formula = "=RANDBETWEEN(1,100)"
' .Value = .Value
' End With
Dim lCell As Range: Set lCell = .Resize(sws.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , , xlPrevious)
If lCell Is Nothing Then Exit Sub ' no data in data range
srCount = lCell.Row - .Row + 1
sData = .Resize(srCount).Value
End With
' Define the destination array.
Dim scCount As Long: scCount = UBound(sData, 2)
Dim drCount As Long
drCount = Int(scCount / scStep) - CLng(scCount Mod scStep > 0)
Dim dData As Variant: ReDim dData(1 To drCount, 1 To srCount)
' Write the data from the source array to the destination array.
Dim r As Long, c As Long
For c = 1 To srCount
For r = 1 To drCount
dData(r, c) = sData(c, (r - 1) * scStep + 1)
Next r
Next c
' Write the values from the destination array to the destination range.
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
With dws.Range(dFirstCellAddress).Resize(, srCount) ' first row range
' Write data.
.Resize(drCount).Value = dData
' Clear below.
.Resize(dws.Rows.Count - .Row - drCount + 1).Offset(drCount).Clear
' Apply some formatting.
'.EntireColumn.AutoFit
End With
' Inform.
MsgBox "Data transposed.", vbInformation
End Sub
My idea is to get the data that I have on "A4" ("Data" worksheet) and paste it 4 times on "B4" ("Forecast" worksheet). After that, take the data from "A5" and do the same (starting from the first blank cell) until there is no more data on the "A" column. After there is no more data, the process should stop.
How do I tell excel to paste the value in the first blank cell in column B ("Forecast" worksheet)?
Sub Test()
Dim wsSource As Worksheet, wsTarget As Worksheet
Dim i As Integer, k As Integer
Set wsSource = ThisWorkbook.Worksheets("Data")
Set wsTarget = ThisWorkbook.Worksheets("Forecast")
k = wsSource.Range("A4", wsSource.Range("A4").End(xlDown)).Rows.Count
For i = 1 To k
wsTarget.Range("B4", "B7").Value = wsSource.Range("A" & 3 + i).Value
Next
End Sub
Copy Repetitions
A Quick Fix
Sub Test()
Dim wsSource As Worksheet, wsTarget As Worksheet
Dim sCell As Range, tCell As Range
Dim i As Long, j As Long, k As Long
Set wsSource = ThisWorkbook.Worksheets("Data")
Set wsTarget = ThisWorkbook.Worksheets("Forecast")
k = wsSource.Range("A4", wsSource.Range("A4").End(xlDown)).Rows.Count
Set sCell = wsSource.Range("A4")
Set tCell = wsTarget.Range("B4")
For i = 1 To k
For j = 1 To 4
tCell.Value = sCell.Value
Set tCell = tCell.Offset(1)
Next j
Set sCell = sCell.Offset(1)
Next i
End Sub
My Choice
Sub CopyRepetitions()
' Source
Const sName As String = "Data"
Const sfCellAddress As String = "A4"
' Destination
Const dName As String = "Forecast"
Const dfCellAddress As String = "B4"
Const Repetitions As Long = 4
' Workbook
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Reference the source (one-column) range ('srg').
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim srg As Range
Dim srCount As Long
With sws.Range(sfCellAddress)
Dim lCell As Range: Set lCell = .Resize(sws.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , , xlPrevious)
If lCell Is Nothing Then Exit Sub ' no data
srCount = lCell.Row - .Row + 1
Set srg = .Resize(srCount)
End With
' Write values from the source range the source array ('sData')
Dim sData As Variant
If srCount = 1 Then
ReDim sData(1 To 1, 1 To 1): sData(1, 1) = srg.Value
Else
sData = srg.Value
End If
' Define the destination array ('dData').
Dim drCount As Long: drCount = srCount * Repetitions
Dim dData As Variant: ReDim dData(1 To drCount, 1 To 1)
' Write the repeating values from the source- to the destination array.
Dim sr As Long
Dim rep As Long
Dim dr As Long
For sr = 1 To srCount
For rep = 1 To Repetitions
dr = dr + 1
dData(dr, 1) = sData(sr, 1)
Next rep
Next sr
' Write the values from the destination array to the destination
' one-column range and clear the data below.
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
With dws.Range(dfCellAddress)
.Resize(drCount).Value = dData
.Resize(dws.Rows.Count - .Row - drCount + 1).Offset(drCount).Clear
End With
' Inform.
MsgBox "Repetitions copied.", vbInformation
End Sub
I have two sheets and I need to get names of fields for each person. For that I need to take a person of a row in sheet2 then i have to get the fields which this person is assigned in the sheet1 on the right table (for every rows). For this part I found and modified this VBA code, but it doesn't do what I need ... :
Dim rgFound As Range
Dim defVal As Range
Dim currParam As Range
Dim currParamDict As Range
With Worksheets("Sheet2")
For Each defVal In .Range("B3", .Range("B" & Rows.Count).End(xlUp)).Offset(, 1)
Set currParam = defVal.Offset(, -1)
If Len(currParam.Value) > 0 Then
Set rgFound = Worksheets("Sheet1").Range("F9:I12").Find(currParam.Value)
If rgFound Is Nothing Then
Debug.Print "Name was not found."
Else
Set currParamDict = rgFound.Offset(, 0)
defVal.Value = currParamDict.Value
End If
End If
Next defVal
End With
I dont know for the range in : Set rgFound = Worksheets("Sheet1").Range("F9:I12").Find(currParam.Value)
I put some example pictures so you can see what it is about.
Sheet1 :
Sheet2 :
After this step, I have to fill the dates corresponding to fields using the left table of the Sheet1...
Fill a Table
Off Track
Ignore possible old data in Sheet2 and write the complete table.
Option Explicit
Sub FillTable()
' Source Dates
Const sdName As String = "Sheet1"
Const sdFirst As String = "B2"
' Source Cities
Const scName As String = "Sheet1"
Const scFirst As String = "F9"
' Destination
Const dName As String = "Sheet2"
Const dFirst As String = "B2"
Const dHeader As String = "Name"
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Source Dates
Dim sdws As Worksheet: Set sdws = wb.Worksheets(sdName)
Dim sdrg As Range: Set sdrg = sdws.Range(sdFirst).CurrentRegion
Dim sdData As Variant: sdData = sdrg.Value
Dim sdrCount As Long: sdrCount = sdrg.Rows.Count
Dim sdcCount As Long: sdcCount = sdrg.Columns.Count
' Source Cities
Dim scws As Worksheet: Set scws = wb.Worksheets(scName)
Dim scrg As Range: Set scrg = scws.Range(scFirst).CurrentRegion
Dim scData As Variant: scData = scrg.Value
Dim schrg As Range: Set schrg = scrg.Rows(1)
Dim scrCount As Long: scrCount = scrg.Rows.Count
Dim sctCount As Long: sctCount = Application.CountA(scrg)
' Destination Array
Dim drCount As Long: drCount = sctCount + 1 ' '+ 1' for headers
Dim dcCount As Long: dcCount = 1 + sdcCount ' 1 for 'Name'
Dim dData As Variant: ReDim dData(1 To drCount, 1 To dcCount)
' Write headers to Destination Array.
Dim sdc As Long
dData(1, 1) = dHeader
For sdc = 1 To sdcCount
dData(1, sdc + 1) = sdData(1, sdc)
Next sdc
' Write 'body' to Destination Array.
Dim dr As Long: dr = 1 ' 1 for headers
Dim sccIndex As Variant
Dim scValue As Variant
Dim sdr As Long
Dim scr As Long
For sdr = 2 To sdrCount
sccIndex = Application.Match(sdData(sdr, 1), schrg, 0)
For scr = 2 To scrCount
scValue = scData(scr, sccIndex)
If Not IsError(scValue) Then
If Len(scValue) > 0 Then
dr = dr + 1
dData(dr, 1) = scValue
For sdc = 1 To sdcCount
dData(dr, sdc + 1) = sdData(sdr, sdc)
Next sdc
End If
End If
Next scr
Next sdr
' Write Destination Array to Destination Range.
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
Dim dfcell As Range: Set dfcell = dws.Range(dFirst)
Dim drg As Range: Set drg = dfcell.Resize(drCount, dcCount)
drg.Value = dData
' Clear Destination Clear Range, the range below Destination Range.
Dim dcrg As Range
Set dcrg = drg.Resize(drg.Worksheet.Rows.Count - drg.Row - drCount + 1) _
.Offset(drCount)
dcrg.Clear ' or 'dcrg.ClearContents'
' Format e.g.:
drg.Rows(1).Font.Bold = True
dws.Range(drg.Columns(3), drg.Columns(dcCount)).Resize(drCount - 1) _
.Offset(1).NumberFormat = "dd/mm/yyyy" ' possibly "dd\/mm\/yyyy"
drg.EntireColumn.AutoFit
'wb.Save
End Sub
Meeting the Requirement
There are the names in Sheet2, so fill the other columns.
Sub FillTable2()
' Source Dates
Const sdName As String = "Sheet1"
Const sdFirst As String = "B2"
' Source Cities
Const scName As String = "Sheet1"
Const scFirst As String = "F9"
' Destination
Const dName As String = "Sheet2"
Const dFirst As String = "B2"
Dim wb As Workbook: Set wb = ThisWorkbook
' Source Dates
Dim sdws As Worksheet: Set sdws = wb.Worksheets(sdName)
Dim sdrg As Range: Set sdrg = sdws.Range(sdFirst).CurrentRegion
Dim sddrg As Range: Set sddrg = sdrg.Resize(sdrg.Rows.Count - 1).Offset(1)
Dim sdData As Variant: sdData = sddrg.Value
Dim sdrlrg As Range: Set sdrlrg = sddrg.Columns(1) ' Row Labels
' Source Cities
Dim scws As Worksheet: Set scws = wb.Worksheets(scName)
Dim scrg As Range: Set scrg = scws.Range(scFirst).CurrentRegion
Dim schRow As Long: schRow = scrg.Row ' Header Row
Dim scdrg As Range: Set scdrg = scrg.Resize(scrg.Rows.Count - 1).Offset(1)
Dim scrCount As Long: scrCount = scdrg.Rows.Count
Dim sccCount As Long: sccCount = scdrg.Columns.Count
' Destination Names
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
Dim dfcell As Range: Set dfcell = dws.Range(dFirst)
Dim drg As Range: Set drg = dfcell.CurrentRegion.Columns(1)
Dim dnrg As Range: Set dnrg = drg.Resize(drg.Rows.Count - 1).Offset(1)
Dim dnData As Variant: dnData = dnrg.Value
' Destination Array
Dim drCount As Long: drCount = dnrg.Rows.Count
Dim dcCount As Long: dcCount = sdrg.Columns.Count
Dim dData As Variant: ReDim dData(1 To drCount, 1 To dcCount)
Dim scCell As Range
Dim dnValue As Variant
Dim scValue As Variant
Dim sdrIndex As Variant
Dim r As Long
Dim c As Long
For r = 1 To drCount
dnValue = dnData(r, 1)
If NoErrorNorBlank(dnValue) Then
Set scCell = Nothing
Set scCell = scdrg.Find(dnValue, _
scdrg.Cells(scrCount, sccCount), xlFormulas, xlWhole)
If Not scCell Is Nothing Then
scValue = scCell.EntireColumn.Rows(schRow).Value
If NoErrorNorBlank(scValue) Then
sdrIndex = Application.Match(scValue, sdrlrg, 0)
If IsNumeric(sdrIndex) Then
For c = 1 To dcCount
dData(r, c) = sdData(sdrIndex, c)
Next c
End If
End If
End If
End If
Next r
Set drg = dnrg.Offset(, 1).Resize(, dcCount)
drg.Value = dData
'wb.Save
End Sub
Function NoErrorNorBlank( _
ByVal CheckValue As Variant) _
As Boolean
If Not IsError(CheckValue) Then
If Len(CheckValue) > 0 Then
NoErrorNorBlank = True
End If
End If
End Function
This line is not identifying a district, but the name in the search itself. Change the statement to reference the data in line 9. I assume that position is fixed, if not then you need another approach.
Set currParamDict = rgFound.Offset(, 0)
' becomes
set currParamDict = Worksheets("sheet1").Cells(9, rgFound.Column)
I have a master sheet being updated by other workbooks. "Column A" in the Master has an ID number, the other spreadsheets will also have a column let's say "B" containing that ID number.
I want to match the ID number from the other workbook to the master and where it matches in column A pull over other columns into the master to fill in the blanks under the correct headings.
I was given this macro, but it's not matching any data.
Sub Macro1()
Dim mastersheet As Worksheet
Set mastersheet = ActiveSheet
For a = 2 To 1000
ValueToCheck = Cells(a, 1).Value
fname = "File location"
Dim Workbooktocheck As Workbook
Set Workbooktocheck = Workbooks.Open("filename")
For b = 2 To 1000
valueInNew = Workbooktocheck.Sheets("Sheet1").Cells(b, 12)
If ValueToCheck = valueInNew Then
mastersheet.Cells(a, 3).Value = Workbooktocheck.Sheets("sheet1").Cells(b, 7)
End If
Next b
Next a
End Sub
Update
This is the master:
This is the spreadsheet that updates:
Match() is usually faster than a nested loop as long as you're only expecting a single matched row.
Try this:
Sub Macro1()
Dim wsMaster As Worksheet, wbToCheck As Workbook, wsCheck As Worksheet
Dim ValueToCheck, a As Long, m
Set wsMaster = ActiveSheet
Set wbToCheck = Workbooks.Open("filepathgoeshere")
Set wsCheck = wbToCheck.Worksheets("Sheet1") '<<< was missing this
For a = 2 To wsMaster.Cells(Rows.Count, 1).End(xlUp).Row
ValueToCheck = wsMaster.Cells(a, 1).Value
If Len(ValueToCheck) > 0 Then
'match is faster than using a nested loop
m = Application.Match(ValueToCheck, wsCheck.Range("L:L"), 0)
If Not IsError(m) Then
'got a match
With wsMaster.Rows(a)
.Columns("C").Value = wsCheck.Cells(m, "G").Value
'etc for other cells...
End With
End If
End If
Next a
End Sub
Update Master Worksheet
Carefully adjust the values in the constants section.
s - Source (read from), d - Destination (written to)
Option Explicit
Sub UpdateMaster()
Const sPath As String = "C:\Test\Source.xlsx"
Const sName As String = "Sheet1"
Const sCol As String = "L"
Const sColsList As String = "A,B,C"
Const sfRow As Long = 1 ' header row
Const dName As String = "Master"
Const dCol As String = "A"
Const dfRow As Long = 1 ' header row
Dim swb As Workbook: Set swb = Workbooks.Open(sPath)
Dim sws As Worksheet: Set sws = swb.Worksheets(sName)
Dim dwb As Workbook: Set dwb = ThisWorkbook ' workbook containing this code
Dim dws As Worksheet: Set dws = dwb.Worksheets(dName)
' Headers
Dim sCols() As String: sCols = Split(sColsList, ",")
Dim cUpper As Long: cUpper = UBound(sCols)
Dim dCols() As Long: ReDim dCols(0 To cUpper)
Dim cIndex As Variant
Dim n As Long
For n = 0 To cUpper
cIndex = Application.Match( _
sws.Rows(sfRow).Columns(sCols(n)), dws.Rows(dfRow), 0)
If IsNumeric(cIndex) Then
dCols(n) = cIndex
Else
MsgBox "A header was not found", vbCritical, "Update Master"
Exit Sub
End If
Next n
' Column Ranges
Dim sfCell As Range: Set sfCell = sws.Cells(sfRow + 1, sCol)
Dim slCell As Range: Set slCell = sws.Cells(sws.Rows.Count, sCol).End(xlUp)
Dim srg As Range: Set srg = sws.Range(sfCell, slCell)
Dim dfCell As Range: Set dfCell = dws.Cells(dfRow + 1, dCol)
Dim dlCell As Range: Set dlCell = dws.Cells(dws.Rows.Count, dCol).End(xlUp)
Dim drg As Range: Set drg = dws.Range(dfCell, dlCell)
' Write
Application.ScreenUpdating = False
Dim dCell As Range
Dim rIndex As Variant
For Each dCell In drg.Cells
rIndex = Application.Match(dCell.Value, srg, 0)
If IsNumeric(rIndex) Then
For n = 0 To cUpper
dCell.EntireRow.Columns(dCols(n)).Value _
= srg.Cells(rIndex).EntireRow.Columns(sCols(n)).Value
Next n
End If
Next dCell
Application.ScreenUpdating = True
' Inform
MsgBox "Data updated.", vbInformation, "Update Master"
End Sub