Copy columns between worksheets using arrays - excel

I want to copy some columns in the active sheet to a workbook which is opened during run time. The attached code is working well, EXCEPT that I want to READ the column headers in the source sheet rather than have them be hard-defined, because they might not be always the same. The lines I want to transfer start at row 2 on the source and should be pasted also on row 2 on the paste file. Thank you!
Here is the code:
Option Explicit
Sub CopyPvtToTemplate()
' Copies the columns in the Source file and pastes them into template
' The Source file is the Active Sheet
Const LastRowColumnS As Long = 2
Const FirstRowS = 2
Const FirstRowP = 2
Dim HeadSource As Variant
Dim HeadPaste As Variant
Dim LastRow As Long
HeadSource = Array("Header Column I", "Header Column E", "Header Column F", "Header Column G", "Header Column H", "Header Column B", "Header Column J")
HeadPaste = Array("Header Column A", "Header Column B", "Header Column C", "Header Column D", "Header Column E", "Header Column F", "Header Column H")
Dim rng As Range
Dim PasteFile As Variant
Dim wsS As Worksheet
Dim wsP As Worksheet
Dim CurColS As Long
Dim CurColP As Long
Dim NumberOfRows As Long
Dim Count As Long
Dim i As Long
' Define Source Worksheet and Last Row in Source file
Set wsS = ActiveSheet
With ActiveSheet
LastRow = .Range("B" & .Rows.Count).End(xlUp).Row
End With
' Open Paste file
Set PasteFile = Workbooks.Open("C:\Users\ etc.xlsx")
' Define Source Worksheet
Set wsP = PasteFile.Worksheets(2)
' Define last cell with data in Last Row Column of Source Sheet
Set rng = wsS.Columns(LastRowColumnS).Find(what:="*", LookIn:=xlFormulas, Searchdirection:=xlPrevious)
If rng Is Nothing Then
MsgBox "No data in column"
Exit Sub
End If
NumberOfRows = rng.Row - FirstRowS + 1
For i = 0 To UBound(HeadSource)
' Define column of current header in Source Sheet
Set rng = wsS.Cells.Find(what:=HeadSource(i), after:=wsS.Cells(wsS.Rows.Count, wsS.Columns.Count), _
LookIn:=xlFormulas, lookat:=xlWhole, searchorder:=xlByRows)
If Not rng Is Nothing Then
CurColS = rng.Column
' Define column of Current Header in Paste sheet
Set rng = wsP.Cells.Find(what:=HeadPaste(i), after:=wsP.Cells(wsP.Rows.Count, wsP.Columns.Count), _
LookIn:=xlFormulas, lookat:=xlWhole, searchorder:=xlByRows)
If Not rng Is Nothing Then
CurColP = rng.Column
' Write data from Source Sheet to Paste Sheet
wsP.Cells(FirstRowP, CurColP).Resize(NumberOfRows).Value = _
wsS.Cells(FirstRowS, CurColS).Resize(NumberOfRows).Value
' Count the transfer
Count = Count + 1
End If
End If
Next i
MsgBox "Transferred data from '" & Count & "'Columns."
End Sub

I think you're setting yourself up for potential errors by taking this approach - i.e. if you don't type the exact text of the column headings / number of headings within your code etc. Also, using ActiveSheet can be fraught with danger. Having said that, the code below should give you what you want - just change the names to the actual headers, as well as the target file. Let me know how you go.
EDIT
Code edited following clarification from OP.
Option Explicit
Sub CopyPvtToTemplate()
On Error GoTo GetOut
Application.EnableEvents = False
Dim LastRow As Long
Dim wb As Workbook, wsS As Worksheet, wsP As Worksheet
Dim sArray, pArray, i As Integer, j As Integer
Dim Scol As Integer, Pcol As Integer
Set wsS = ActiveSheet
Set wb = Workbooks.Open(ThisWorkbook.Path & "\etc.xlsx") '<~~ change to suit
Set wsP = wb.Sheets(2)
LastRow = wsS.Cells(Rows.Count, 2).End(xlUp).Row
sArray = Array(9, 5, 6, 7, 8, 2, 10)
pArray = Array(1, 2, 3, 4, 5, 6, 8)
For i = 0 To UBound(sArray)
Scol = sArray(i)
For j = 0 To UBound(pArray)
Pcol = pArray(i)
wsS.Range(wsS.Cells(2, Scol), wsS.Cells(LastRow, Scol)).Copy wsP.Cells(2, Pcol)
Next j
Next i
MsgBox "Transferred data from " & i & " columns"
Continue:
Application.EnableEvents = True
Exit Sub
GetOut:
MsgBox Err.Description
Resume Continue
End Sub

Related

Find column based on header and remove first 3 characters starting from 2 row

I need help to remove character from a column with particular header.
I have a spreadsheet with headers (IP, hostname, Asset Group). I need to remove the first 3 characters from each row of the column called "Asset Group" (excluding header name (row 1)). Basically, I want to get rid of the "VM " from that column. I have a problem how to refer to that particular column "Asset Group". Thank you in advance!
Dim SelRange As Range
Dim ColNum As Integer
Dim CWS As Worksheet
'Find the column number where the column header is Asset Group
Set CWS = ActiveSheet
ColNum = Application.WorksheetFunction.Match("Asset Group", CWS.Rows(1), 0)
LastColumn = Cells(1, CWS.Columns.Count).End(xlToLeft).Column
For i = 2 To LastColumn
...
Next i
End With
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
You can try something like the following
Dim CWS As Worksheet
Dim AssetHdr as Range
Dim tmp as Variant
Dim i as Long
Set CWS = ActiveSheet
' Find Header Column
Set AssetHdr = CWS.Rows(1).Find(what:="Asset Group")
' Test if Header was found
If Not AssetHdr is Nothing Then
With CWS
' Get Last Row in Column
NoRow = .Cells(.Rows.Count, AssetHdr.Column).End(xlUp).Row
' Store in array
tmp = Application.Transpose(.Range(.Cells(2, AssetHdr.Column), .Cells(NoRow, AssetHdr.Column))).Value2
' Remove first 3 characters
For i = LBound(tmp) to UBound(tmp)
tmp(i) = Right(tmp(i), Len(tmp(i))-3)
Next i
' Write back to sheet
.Cells(2, AssetHdr.Column).Resize(ubound(tmp)-1).Value2 = tmp
End With
End If
Replace Partial Strings in a Range
Application.Match allows you to test its result with IsError or IsNumeric, while WorksheetFunction.Match raises an error if no match.
With the Range.Replace method you can replace values in a range in one go.
Option Explicit
Sub ReplacePartialString()
Dim cws As Worksheet: Set cws = ActiveSheet
Dim ColNum As Variant
ColNum = Application.Match("Asset Group", cws.Rows(1), 0)
If IsError(ColNum) Then
MsgBox "Column 'Asset Group' not found.", vbCritical
Exit Sub
End If
Dim LastCell As Range
Set LastCell = cws.Cells(cws.Rows.Count, ColNum).End(xlUp)
If LastCell.Row < 2 Then
MsgBox "No data found.", vbCritical
Exit Sub
End If
Dim crg As Range: Set crg = cws.Range(cws.Cells(2, ColNum), LastCell)
crg.Replace "VM ", "", xlPart, , True
End Sub
I was able to figure it out how to do it, the way I started. Thanks for the answer #VBasic2008, you created a better one with catching errors.
Dim CWS As Worksheet
Set CWS = ActiveSheet
ColNum = Application.WorksheetFunction.Match("Asset Group", CWS.Rows(1), 0)
With CWS
LR = .Cells(.Rows.Count, ColNum).End(xlUp).Row
End With
For i = 2 To LR
CWS.Cells(i, ColNum) = Right(CWS.Cells(i, ColNum).Value, Len(CWS.Cells(i, ColNum).Value) - 3)
Next i

Excel Row paste with VBA

Hi guys i need some help on VBA.
I have range of numbers in sheet 1 from cells A6:O29. Next I have specific numbers selected in Sheet 3 in Column "B".
[![enter image description here][1]][1]
[![enter image description here][2]][2]
I want to loop throw each value in Sheet 3 Column B and find that specific value in Sheet 1 range A6:O29
Next it should paste Entire Row from Sheet 1 starting From Column (Q:CF) in Sheet 3 Starting from Column C onwards
I have coded it but its not working.
Private Sub CommandButton1_Click()
Dim main As Worksheet
Dim outcome As Worksheet
'main sheet contains Range to search number in
Set main = ThisWorkbook.Sheets("Sheet1")
'outcome sheet has specific values in Column B
Set outcome = ThisWorkbook.Sheets("Sheet3")
'column B values are considrered as doubles
Dim valuesfind As Double
'range where values are to be found
Dim myrange As Range
Set myrange = Worksheets("Sheet1").Range("A6:O29")
'no of times to loop code based on values in outcomesheet
locations = Worksheets("Sheet3").Cells(Rows.Count, 2).End(xlUp).Row
For i = 6 To locations
degrees = outcome.Range("B" & i).Value
For b = 6 To Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
If main.Range("A6:O29" & b).Value = degrees Then
outecome.Range("C:BR" & i).Value = main.Range("Q:CF" & b).Value
Exit For
End If
Next b
Next i
End Sub
[1]: https://i.stack.imgur.com/uBo66m.png
[2]: https://i.stack.imgur.com/D0bRUm.png
Please remember to declare all variables, add Option Explicit at the top of your module to help you enforce it.
Try the code below:
Option Explicit
Private Sub CommandButton1_Click()
'main sheet contains Range to search number in
Dim main As Worksheet
Set main = ThisWorkbook.Sheets("Sheet1")
Const mainCopyRng As String = "Q?:CF?"
'outcome sheet has specific values in Column B
Dim outcome As Worksheet
Set outcome = ThisWorkbook.Sheets("Sheet3")
Const outcomePasteRng As String = "C?:BR?"
'range where values are to be found
Dim myrange As Range
Set myrange = main.Range("A6:O29")
'no of times to loop code based on values in outcomesheet
Dim outcomeLastRow As Long
outcomeLastRow = outcome.Cells(Rows.Count, 2).End(xlUp).Row
Dim i As Long
For i = 6 To outcomeLastRow
Dim Degrees As Double
Degrees = outcome.Cells(i, 2).Value
Dim searchRng As Range
Set searchRng = myrange.Find(Degrees, LookIn:=xlValues, LookAt:=xlWhole)
If Not searchRng Is Nothing Then
Dim searchRow As Long
searchRow = searchRng.Row
outcome.Range(Replace(outcomePasteRng, "?", i)).Value = main.Range(Replace(mainCopyRng, "?", searchRow)).Value
End If
Next i
End Sub
This should work.
Sub Test()
Dim main As Worksheet
Set main = ThisWorkbook.Sheets("Sheet1")
Dim myrange As Range
Set myrange = main.Range("A6:O29")
Dim outcome As Worksheet
Set outcome = ThisWorkbook.Sheets("Sheet3")
'Set reference to locations in sheet3.
Dim locations As Range
With outcome
Set locations = .Range(.Cells(1, 2), .Cells(Rows.Count, 2).End(xlUp))
End With
'Search for each location in Sheet1 and if found copy to Sheet3.
Dim location As Range
Dim FoundLocation As Range
For Each location In locations
Set FoundLocation = myrange.Find( _
What:=location, _
After:=myrange.Cells(1, 1), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext)
If Not FoundLocation Is Nothing Then
main.Cells(FoundLocation.Row, 1).Resize(, 15).Copy _
Destination:=location.Offset(, 1)
End If
Next location
End Sub

searching for matches between two sheets and copying specific values from specific column

i have 2 sheets , in sheet1 i have a column with article names(im geeting my names from sheet1) , in sheet 2 i have a column like that two "Nom de l'entité" (doing a search by header in sheet 2), if i find a match in sheet 2 , i look for a column called "longueur" and copy the value and put it in the offset(0,1) of the article name in sheet 1 . Im a beginner but this is what i did so far.I need to loop through all the article names hoping to fin them all in sheet 2 . Here's a link of photo to see what im trying to do exactly : https://postimg.cc/pmLY9dXc
Sub longueur()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Lecture") '<== Sheet that has raw data
Dim wss As Worksheet: Set wss = ThisWorkbook.Sheets("Feuil1") 'sheet that we re gonna paste longueur into
Dim FoundName As Range, FoundLongueur As Range
Dim c As Range
Set FoundName = ws.Range("A1:DS1").Find("NOM DE L'ENTITÉ") '<== Header name to search for
Set FoundLongueur = ws.Range("A1:DS1").Find("LONGUEUR") '<== Header name to search for in case we already found name match
If Not FoundName Is Nothing And Not FoundLongueur Is Nothing Then
For Each c In Range(wss.Cells.Range("D:D")) 'go back to sheet1 to get the names to search for
If c.value = FoundName Then
FoundLongueur.Offset(0, 1).value
End If
Next c
End If
End Sub
Try
Option Explicit
Sub longueur()
Dim wb As Workbook, ws1 As Worksheet, ws2 As Worksheet
Dim rngName As Range, rng As Range, c As Range
Dim colLongueur As Integer, iLastRow As Long
Set wb = ThisWorkbook
Set ws1 = wb.Sheets("Feuil1") 'sheet that we re gonna paste longueur into
Set ws2 = wb.Sheets("Lecture") '<== Sheet that has raw data
' find column NOM DE L'ENTITÉ on sheet 2
Set rng = ws2.Range("A1:DS1").Find("NOM DE L'ENTITÉ")
If rng Is Nothing Then
MsgBox "Could not find 'NOM DE L'ENTITÉ' on " & ws2.Name, vbCritical
Exit Sub
End If
' expand to end of column
Set rngName = ws2.Range(rng, ws2.Cells(Rows.Count, rng.Column).End(xlUp))
' find column LONGUEUR on sheet 2
Set rng = ws2.Range("A1:DS1").Find("LONGUEUR")
If rng Is Nothing Then
MsgBox "Could not find 'LONGUEUR' on " & ws2.Name, vbCritical
Exit Sub
End If
colLongueur = rng.Column
' scan sheet 1 col D
iLastRow = ws1.Cells(Rows.Count, "D").End(xlUp).Row
For Each c In ws1.Range("D1:D" & iLastRow)
' find name on sheet 2
Set rng = rngName.Find(c.Value, LookIn:=xlValues, LookAt:=xlWhole)
If rng Is Nothing Then
c.Offset(0, 1).Value = "No Match"
Else
' copy value from column LONGUEUR
c.Offset(0, 1).Value = ws2.Cells(rng.Row, colLongueur)
End If
Next
MsgBox "Ended"
End Sub

Copy/Paste columns

I have several columns with headers in one excel workbook, I want to copy some of these columns into another workbook.
Let’s say I have my origin workbook:
Ident|Name|Code|Part|Desc|U|Total
These are the headers of the columns with some data below them.
And I want to copy only the data in the columns Ident, Code and Part in another workbook that has the same headers but in a different order with the exception that one header has a different name:
Code|Ident|Piece
It is blank and Piece corresponds to Part.
So I want a code that takes the data from the origin workbook and copy it to the destination workbook. Also if possible I’d like that you can choose the original workbook from a file as I have different excel files to choose from.
Thank you for your answers. I have never used VBA and I’m trying to learn.
I have the following code that lets you choose the data you want manually but I want something similar that does it automatically after recognizing the headers.
Sub ImportDatafromotherworksheet()
Dim wkbCrntWorkBook As Workbook
Dim wkbSourceBook As Workbook
Dim rngSourceRange As Range
Dim rngDestination As Range
Set wkbCrntWorkBook = ActiveWorkbook
With Application.FileDialog(msoFileDialogOpen)
.Filters.Clear
.Filters.Add "Excel 2007-13", "*.xlsx; *.xlsm; *.xlsa"
.AllowMultiSelect = False
.Show
If .SelectedItems.Count > 0 Then
Workbooks.Open .SelectedItems(1)
Set wkbSourceBook = ActiveWorkbook
Set rngSourceRange = Application.InputBox(prompt:="Select source range", Title:="Source Range", Default:="A1", Type:=8)
wkbCrntWorkBook.Activate
Set rngDestination = Application.InputBox(prompt:="Select destination cell", Title:="Select Destination", Default:="A1", Type:=8)
rngSourceRange.Copy rngDestination
rngDestination.CurrentRegion.EntireColumn.AutoFit
wkbSourceBook.Close False
End If
End With
End Sub
I add here some part I modified:
arrC = Split("CODE|ident|Piece", "|")
lastColO = shO.Cells(1, Cells.Columns.Count).End(xlToLeft).Column
arrO = shO.Range(shO.Cells(1, 1), shO.Cells(1, lastColO)).Value
'Copy the columns:
arrC = Split("CODE|ident|Piece", "|")
lastColO = shO.Cells(1, Cells.Columns.Count).End(xlToLeft).Column
arrO = shO.Range(shO.Cells(1, 1), shO.Cells(1, lastColO)).Value
'Copy the columns:
For j = 0 To UBound(arrC)
If arrC(j) = "Ident" Then strH = "ident" Else strH = arrC(j)
If arrC(j) = "Code" Then strH = "CODE" Else strH = arrC(j)
If arrC(j) = "Piece" Then strH = "Part" Else strH = arrC(j)
For i = 1 To UBound(arrO, 2)
If arrO(1, i) = strH Then
lastRowO = shO.Cells(Rows.Count, i).End(xlUp).Row 'last row of the found orig header column
lastRowC = shC.Cells(Rows.Count, j + 1).End(xlUp).Row 'last row of toCopy sheet header column
arrTransf = shO.Range(shO.Cells(2, i), shO.Cells(lastRowO, i)).Value
Set copyCell = shC.Range(shC.Range("A1"), shC.Cells(1, lastColO)).Find(arrC(j))
If copyCell Is Nothing Then MsgBox "There is not a column named """ & _
arrC(j) & """ in the page to Copy.": Exit Sub
copyCell.Offset(1, 0).Resize(UBound(arrTransf, 1), UBound(arrTransf, 2)).Value = arrTransf
End If
Next i
Next j
End Sub
Try this code, please. It copies columns from the active sheet to shC worksheet, which must be set in the code below:
Sub moveColumnsContent()
Dim shO As Worksheet, shC As Worksheet, lastRowO As Long, lastRowC As Long
Dim arrO As Variant, arrC As Variant, lastColO As Long, lastColC As Long
Dim El As Variant, arrTransf As Variant, strH As String, copyCell As Range
Dim wbNumb As Variant, wb As Workbook, ws As Worksheet, strWB As String
Dim WbC As Workbook, sh As Worksheet, strWh As String, shNunb As String
Dim i As Long, j As Long
Set shC = ActiveSheet
WbSelection:
For i = 1 To Workbooks.count
strWB = strWB & Workbooks(i).Name & " - " & i & vbCrLf
Next i
wbNumb = InputBox("Please, write the the right workbook name number to be chosen:" & vbCrLf & _
vbCrLf & strWB, "Choose the workbook from where to copy columns!", 1)
If wbNumb = "" Then MsgBox "You did not select anything and code stops!"
Exit Sub
If IsNumeric(wbNumb) Then
On Error Resume Next
Set WbC = Workbooks(CLng(wbNumb))
if Err.Number<> 0 Then
Err.Clear: On Error GoTo 0:Exit Sub
End If
On Error GoTo 0
Else
MsgBox "Please select the number to the right side of the chosen workbook!": GoTo WbSelection
End If
WsSelection:
For i = 1 To WbC.Worksheets.count
strWh = strWh & WbC.Worksheets(i).Name & " - " & i & vbCrLf
Next
shNunb = InputBox("Please, write the the right sheet name number to be chosen:" & vbCrLf & _
vbCrLf & strWh, "Select the worksheet to be used for copying the columns!", 1)
If shNunb = "" Then MsgBox "Please select a worksheet number to be selected for copying columns!": _
GoTo WsSelection
Set shO = WbC.Worksheets(CLng(shNunb))
arrC = Split("Code|Ident|Piece", "|")
lastColO = shO.Cells(1, Cells.Columns.count).End(xlToLeft).Column
arrO = shO.Range(shO.Cells(1, 1), shO.Cells(1, lastColO)).value
'Copy the columns:
For j = 0 To UBound(arrC)
If arrC(j) = "Piece" Then strH = "Part" Else strH = arrC(j)
For i = 1 To UBound(arrO, 2)
If arrO(1, i) = strH Then
lastRowO = shO.Cells(Rows.count, i).End(xlUp).Row 'last row of the found orig header column
lastRowC = shC.Cells(Rows.count, j + 1).End(xlUp).Row 'last row of toCopy sheet header column
arrTransf = shO.Range(shO.Cells(2, i), shO.Cells(lastRowO, i)).value
Set copyCell = shC.Range(shC.Range("A1"), shC.Cells(1, lastColO)).Find(arrC(j))
If copyCell Is Nothing Then MsgBox "There is not a column named """ & _
arrC(j) & """ in the page to Copy.": Exit Sub
copyCell.Offset(1, 0).Resize(UBound(arrTransf, 1), UBound(arrTransf, 2)).value = arrTransf
End If
Next i
Next j
End Sub
If you will need more headers in the sheet to copy, it is enough to add them in "Code|Ident|Piece" string.
Now, trying to think how it would be more convenient for you to use it, probably, a better way would be to name the sheet where from the columns will be copied, in a specific way (maybe "MasterSheet") and copy the columns to the active one. Or, iterate between all Workbook sheets and do this process automatically. But, please, try the code as it is and let me know how looks more convenient for you.
If your intention is to extract a three columns set in the fixed order Code|Ident|Part=Piece copying them to the first three target columns A:C, you may try the following Rearrange procedure executing these steps:
[0-1] get source data
[2 ] rearrange columns of source data in a given order by a one-liner instead of copying separate columns arrays each time
[3 ] write (rearranged) data to target sheet
Sub Rearrange(src As Worksheet, tgt As Worksheet)
'Purpose: extract and rearrange data array columns
'Author: https://stackoverflow.com/users/6460297/t-m
With src
'[0] get last row of source data in column A:A (Ident)
Dim lastRow As Long: lastRow = .Range("A" & .Rows.Count).End(xlUp).Row
'[1] assign data to (1-based) 2-dim variant datafield array
Dim data: data = .Range("A2:G" & lastRow)
'[2] rearrange columns
' where Array(3,1,4) gets the 3rd, 1st and 4th column only
' (and Evaluate("ROW(1:nnn)") gets the entire row set)
data = Application.Index(data, Evaluate("ROW(1:" & (lastRow - 1) & ")"), Array(3, 1, 4))
End With
'[3] write (rearranged) data to target sheet
tgt.Range("A2").Resize(UBound(data), 3) = data
End Sub
If, however you are confronted with a variable target column structure you might play around with Moving columns based on header name and change it to your needs :-)
This should work, you only need to tweak the target sheet and, if it were the case, add more cases where origin/target have different column names:
Option Explicit
Sub Main()
Dim arrOrigin As Variant: arrOrigin = GetArrayFromSheet
Dim OriginHeaders As New Dictionary: Set OriginHeaders = GetOriginHeaders(arrOrigin)
With ThisWorkbook.Sheets("Your target sheet name") 'change this name
Dim arrTarget As Variant: ReDim arrTarget(1 To UBound(arrOrigin), _
1 To .UsedRange.Columns.Count)
'Last row on column 1 (or column A)
Dim LastRow As Long: LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row + 1
End With
Dim TargetHeaders As New Dictionary: Set TargetHeaders = GetTargetHeaders(arrTarget)
Dim i As Long
Dim Key As Variant
Dim OriginColumn As Long, TargetColumn As Long
Dim x As Long: x = 1
For i = 2 To UBound(arrOrigin)
For Each Key In TargetHeaders.Keys
OriginColumn = OriginHeaders(Split(TargetHeaders(Key), "\")(0))
TargetColumn = Split(TargetHeaders(Key), "\")(1)
arrTarget(x, TargetColumn) = arrOrigin(i, OriginColumn)
Next Key
Next i
ThisWorkbook.Sheets("Your target sheet name").Range("A" & LastRow).Resize(UBound(arrTarget), UBound(arrTarget, 2)).Value = arrTarget
End Sub
Private Function GetArrayFromSheet() As Variant
Dim wb As Workbook: Set wb = FilePicker
Dim ws As Worksheet
For Each ws In wb.Sheets
If ws.Name Like "* Annex 1" Then
GetArrayFromSheet = ws.UsedRange.Value
wb.Close False
Exit Function
End If
Next ws
End Function
Private Function FilePicker() As Workbook
With Application.FileDialog(msoFileDialogOpen)
.Filters.Clear
.Filters.Add "Excel 2007-13", "*.xlsx; *.xlsm; *.xlsa"
.AllowMultiSelect = False
.Show
If .SelectedItems.Count > 0 Then
Set FilePicker = Workbooks.Open(.SelectedItems(1))
Else
MsgBox "No file was selected, the procedure will end"
End
End If
End With
End Function
Private Function GetOriginHeaders(arr As Variant) As Dictionary
Set GetOriginHeaders = New Dictionary
Dim i As Long
For i = 1 To UBound(arr, 2)
GetOriginHeaders.Add arr(1, i), i
Next i
End Function
Private Function GetTargetHeaders(arr As Variant) As Dictionary
Set GetOriginHeaders = New Dictionary
Dim i As Long
Dim MyHeader As String
For i = 1 To UBound(arr, 2)
MyHeader = arr(1, i)
Select Case MyHeader
Case "Piece"
MyHeader = "Part"
'..More cases for different names
End Select
TargetHeaders.Add arr(1, i), MyHeader & "\" & i
Next i
End Function

Search multiple headings(Columns) in other sheet, copy data and paste in main file

I need a VBA code for a button which when clicked browse for other excel file, search for specific sheet named “Farmer History” in it. In this sheet it looks for A1 complete row and search heading “Crop Area” and copy this column data to main file(where button embedded) in sheet named “Berkhund” at F Column below last cell is used.
The same to be done for other 2 columns too i.e
Looks for “Target Qty” in first row at same sheet “Farmer History” and paste in main file sheet “Berkhund” at R Column below last cell is used
Looks for “Commulative Sold” in first row at same sheet “Farmer History” and paste in main file sheet “Berkhund” at S Column below last cell is used.Code which i tried is given below but it cannot BROWSE for file, search and paste back in main file:
Sub copycroparea()
Dim sh As Worksheet, fn As Range
Set sh = Sheets("Farmer History")
Set fn = sh.Rows(1).Find(" Crop Area", , xlValues, xlWhole)
If Not fn Is Nothing Then
fn.Offset(1).Resize(sh.Cells(Rows.Count, fn.Column).End(xlUp).Row, 1).Copy
Sheets("Berkhund").Range("F13")
Else
MsgBox "Crop area Not Found!"
Exit Sub
End If
End Sub
Define an array with the 3 search terms and target coumns and use them in a loop.
Option Explicit
Sub copycroparea()
Const RESULT = "Sheet2" '"Berkhund"
Const SOURCE = "Farmer History"
Dim term(3) As Variant
term(1) = Array("Crop Area", 6) 'F
term(2) = Array("Target Qty", 18) 'R
term(3) = Array("Commulative Sold", 19) 'S
Dim wb As Workbook, ws As Worksheet
Dim wbSearch As Workbook, wsSearch As Worksheet
Dim iTargetRow As Long, iLastRow As Long, sFilename As String
' search for file
sFilename = Application.GetOpenFilename("Excel Files (*.xlsx; *.xlsm),*.xlsx;*.xlsm")
If Len(sFilename) = 0 Or sFilename = "False" Then
MsgBox "No file selected ", vbCritical
End If
'Debug.Print sFilename
Set wb = ThisWorkbook
Set ws = wb.Sheets(RESULT)
Set wbSearch = Workbooks.Open(sFilename, False, True) ' no links update, read only
Set wsSearch = wbSearch.Sheets(SOURCE)
Dim i As Integer, sTerm As String, iCol As Integer, msg As String
Dim rng As Range, rngTarget As Range
For i = 1 To UBound(term)
sTerm = term(i)(0)
iCol = term(i)(1)
'Debug.Print i, sTerm, iCol
Set rng = wsSearch.Rows(1).Find(sTerm, , xlValues, xlPart)
If Not rng Is Nothing Then
' Destination for copy on main file
Set rngTarget = ws.Cells(Rows.Count, iCol).End(xlUp).Offset(1, 0)
' find extent of data
iLastRow = wsSearch.Cells(Rows.Count, rng.Column).End(xlUp).Row
'Debug.Print rngTarget.Address, iLastRow
' copy
rng.Offset(1, 0).Resize(iLastRow, 1).Copy rngTarget
msg = msg & sTerm & " found at " & rng.Address & vbCr
Else
msg = msg & sTerm & "not found" & vbCr
End If
Next
wbSearch.Close False
MsgBox msg, vbInformation
End Sub

Resources