Excel two column of different file comparison and replace next column - excel

Hi I want to compare two excel files and if any strings in file1 coumun B batches with File2 ColumnA then I want to replace corresponding File2's ColumB with File1 Column C
eg:
if File 1, B3 matches with File2 A5 then I want to replace string in B5 of file 2 with C3 of file1

Assume that File1 location is "C:\test\File1.xlsx"
so you can import File1:column A values to File2:column K by formula
File2:K1 formule
='C:\test\[File1.xlsx]Sheet1'!A1
File2:K2 formule
='C:\test\[File1.xlsx]Sheet1'!A2
and so on
Now it is easy to write formulas in File2 depends on imported values

Column Comparison Worksheet Update
Carefully adjust the constants including the Workbooks.
Copy the code into a standard module (e.g. Module1).
The Code
Option Explicit
Sub updateWorksheet()
' Source
Const srcWb As String = "Source.xlsm"
Const srcWs As String = "Sheet1"
Const srcFirstRow As Long = 2
Const srcCriteria As Variant = "B"
Const srcValue As Variant = "C"
' Target
Const tgtWb As String = "Target.xlsm"
Const tgtWs As String = "Sheet2"
Const tgtFirstRow As Long = 2
Const tgtCriteria As Variant = "A"
Const tgtValue As Variant = "B"
' Workbooks
Dim wbSrc As Workbook: Set wbSrc = Workbooks(srcWb)
'Dim wbSrc As Workbook: Set wbSrc = ThisWorkbook
Dim wbTgt As Workbook: Set wbTgt = Workbooks(tgtWb)
'Dim wbTgt As Workbook: Set wbTgt = ThisWorkbook
' Write values from Source Range to Source Array.
Dim src As Worksheet: Set src = wbSrc.Worksheets(srcWs)
Dim rng As Range
Set rng = src.Columns(srcCriteria).Find("*", , xlValues, , , xlPrevious)
If rng Is Nothing Then Exit Sub
If rng.Row < srcFirstRow Then Exit Sub
Set rng = src.Range(src.Cells(srcFirstRow, srcCriteria), rng)
Dim Source(1) As Variant: Source(0) = rng.Value
Source(1) = rng.Offset(, src.Columns(srcValue).Column - rng.Column).Value
' Write values from Target Range to Target Array.
Dim tgt As Worksheet: Set tgt = wbTgt.Worksheets(tgtWs)
Set rng = tgt.Columns(tgtCriteria).Find("*", , xlValues, , , xlPrevious)
If rng Is Nothing Then Exit Sub
If rng.Row < tgtFirstRow Then Exit Sub
Set rng = tgt.Range(tgt.Cells(tgtFirstRow, tgtCriteria), rng)
Dim Target(1) As Variant: Target(0) = rng.Value
Set rng = rng.Offset(, tgt.Columns(tgtValue).Column - rng.Column)
Target(1) = rng.Value
Dim Curr As Variant
' Write from Source Array to Target Array.
Dim i As Long
For i = 1 To UBound(Target(0))
Curr = Application.Match(Target(0)(i, 1), Source(0), 0)
If Not IsError(Curr) Then
Target(1)(i, 1) = Source(1)(Curr, 1)
End If
Next i
' Write from Target Array to Target Range.
rng.Value = Target(1)
' Inform user.
MsgBox "Data transferred.", vbInformation, "Success"
End Sub

Related

if condition only few steps true VBA/Excel

enter image description hereFor a larger project I need to change the source of values for a column all n*k steps, with n being a rational and k a natural number.
Edit for better understanding:
I have a column with multiple entries (filled by a loop in a makro) and need to find all entries with a common divisor called "testwer" in my makro. This "testwer" should later be editable in an excel sheet via a cellinput (in this case G2)
I've tried by writing a macro , a simplified example looks like the following:
Sub testmam()
Dim testwer, i, j
i = 1
j = 1
testwer = Range("g2").Value 'gets the rational number n
Do Until i = 18 'until end of entries in column is reached
If Cells(i, 1).Value = testwer * j Then 'if cellvalue = n*1,2,...,infty
Cells(i, 2).Value = j 'some output in another cell to check wether the detection was sucessfull
j = j + 1 'check coming cells for next value of n*k
End If
i = i + 1
Loop
End Sub
However, when I run this, it only detects the first few (3-5) solutions. For example for n being 1.5 it found only 1.5, 3 and 4.5 to be true. Starting from values 6 to all following multipliers of 1.5 the if condition seems to turn out false.
Does someone know how this could happen? As the if condition is true for multiple steps, I assume the syntax isn't completely wrong.
Greets
Detect Multipliers
Compact
Sub TestMamCompact()
Const wsName As String = "Sheet1"
Const SourceFirstCellAddress As String = "A1"
Const TestCellAddress As String = "G2"
Const DestinationColumn As String = "B"
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim ws As Worksheet: Set ws = wb.Worksheets(wsName)
Dim sfCell As Range: Set sfCell = ws.Range(SourceFirstCellAddress)
Dim slCell As Range
Set slCell = ws.Cells(ws.Rows.Count, sfCell.Column).End(xlUp)
If slCell.Row < sfCell.Row Then Exit Sub ' no data
Dim srg As Range: Set srg = ws.Range(sfCell, slCell)
Dim TestWert As Double: TestWert = ws.Range(TestCellAddress).Value
Dim k As Long: k = 1
Dim sCell As Range
For Each sCell In srg.Cells
If IsNumeric(sCell) Then
If sCell.Value = TestWert * k Then
ws.Cells(sCell.Row, DestinationColumn).Value = k
k = k + 1
End If
End If
Next sCell
MsgBox "Results written.", vbInformation
End Sub
Argumented
Sub TestMamTEST()
Const wsName As String = "Sheet1"
Const SourceFirstCellAddress As String = "A1"
Const TestCellAddress As String = "G2"
Const DestinationColumn As String = "B"
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim ws As Worksheet: Set ws = wb.Worksheets(wsName)
Dim sfCell As Range: Set sfCell = ws.Range(SourceFirstCellAddress)
TestMam sfCell, TestCellAddress, DestinationColumn
' or just:
'TestMam sfCell, "G2", "B"
End Sub
Sub TestMamOneLinerTEST()
TestMam ThisWorkbook.Worksheets("Sheet1").Range("A1"), "G2", "B"
End Sub
Sub TestMam( _
ByVal SourceFirstCell As Range, _
ByVal TestCellAddress As String, _
ByVal DestinationColumn As String)
Dim ws As Worksheet: Set ws = SourceFirstCell.Worksheet
Dim slCell As Range
Set slCell = ws.Cells(ws.Rows.Count, SourceFirstCell.Column).End(xlUp)
If slCell.Row < SourceFirstCell.Row Then Exit Sub ' no data
Dim srg As Range: Set srg = ws.Range(SourceFirstCell, slCell)
Dim TestWert As Double: TestWert = ws.Range(TestCellAddress).Value
Dim k As Long: k = 1
Dim sCell As Range
For Each sCell In srg.Cells
If IsNumeric(sCell) Then
If sCell.Value = TestWert * k Then
ws.Cells(sCell.Row, DestinationColumn).Value = k
k = k + 1
End If
End If
Next sCell
MsgBox "Results written.", vbInformation
End Sub

Find value in another sheet and return value to the right

I want to take the active cell in the For Each, "vlookup" it in another sheet, and bring back the value from the cell to the right of it.
The problem is in .find(cell.value).
Option Explicit
Sub EmailRep()
Dim range1, range2, cell As Range
Dim ult_email As String
Dim ult_linha As Integer
Dim linha_atual As Integer
Dim Email_atual As String
Set range2 = Sheets("Planilha1").Range("B2:B21")
Set range1 = Range("D4:D19")
linha_atual = range1.Cells(1, 1).Row
ult_linha = 19
ult_email = Email_atual
Email_atual = ult_email
For Each cell In range1
If cell.Value <> ult_email Then
Email_atual = cell.Value
ult_email = cell.Value
Else
cell.Value = range2.Find(cell.Value).Offset(1, 1)
MsgBox (cell)
End If
linha_atual = linha_atual + 1
Next
End Sub
A VBA Lookup (Loop, Dictionary)
This may not be what you need but check it out. It will return the unique column pairs of one two-column range in another worksheet's two-column range.
Adjust (play with) the values in the constants section (a second worksheet name was never mentioned).
Option Explicit
Sub EmailRep()
' Source (Read)
Const sName As String = "Planilha1"
Const sfCol As String = "A"
Const sfRow As Long = 2
' Destination (Write)
Const dName As String = "Planilha2"
Const dfCol As String = "D"
Const dfRow As Long = 4
Const DoClearBelow As Boolean = True
Const DoSort As Boolean = True
' Both
Const Delimiter As String = "|" ' something that doesn't appear in the data
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Reference the source range.
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim slRow As Long: slRow = sws.Cells(sws.Rows.Count, sfCol).End(xlUp).Row
Dim srg As Range: Set srg = sws.Range( _
sws.Cells(sfRow, sfCol), sws.Cells(slRow, sfCol)).Resize(, 2)
' Write from the source range to the dictionary.
Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
dict.CompareMode = vbTextCompare
Dim srrg As Range
Dim sString As String
For Each srrg In srg.Rows ' loop through rows
sString = srrg.Cells(1) & Delimiter & srrg.Cells(2)
dict(sString) = Empty
Next srrg
Dim rCount As Long: rCount = dict.Count
Application.ScreenUpdating = False
' Write from the dictionary to the destination range.
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
Dim drg As Range: Set drg = dws.Cells(dfRow, dfCol).Resize(rCount, 2)
Dim Key As Variant
Dim r As Long
For Each Key In dict.Keys
r = r + 1
drg.Rows(r).Value = Split(Key, Delimiter)
Next Key
' Clear below.
If DoClearBelow Then
drg.Resize(dws.Rows.Count - drg.Row - rCount + 1).Offset(rCount).Clear
End If
' Sort.
If DoSort Then drg.Sort drg.Columns(1), xlAscending
Application.ScreenUpdating = True
MsgBox "Data created.", vbInformation
End Sub

Using single cell in loop as trigger to to copy multiple ranges VBA

The macro is working with hard coded inputs but I need loops for debugging and future growth. I don't know the best way to set this up.
Range("b3:b8:) are the cells I would like to loop over.
If cell.value = 1 then
Set var1 = range("a3:aq3") (* This range always has the same row number as cell in loop*)
Set var2 = range("a9:aq9") (*This range always 6 greater than row of cell in loop.)
End if
Next cell
Thanks
Loop Through Rows of a Range
Option Explicit
Sub LoopThroughRows()
Const srgAddress As String = "A3:AQ8"
Const scCol As Long = 2
Const sCriteria As String = "1"
Dim sws As Worksheet: Set sws = ActiveSheet ' improve, e.g.:
'Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
'Dim sws As Worksheet: Set sws = wb.Worksheets("Sheet1")
Dim srg As Range: Set srg = sws.Range(srgAddress) ' last use of 'sws'
Dim srCount As Long: srCount = srg.Rows.Count
Dim srg1 As Range
Dim srg2 As Range
Dim sCell As Range
Dim sr As Long
For Each sCell In srg.Columns(scCol).Cells ' don't forget '.Cells'!
sr = sr + 1 ' monitoring each range row (not worksheet row)
If CStr(sCell.Value) = sCriteria Then ' also avoiding error values
Set srg1 = srg.Rows(sr)
Set srg2 = srg1.Offset(srCount)
' Continue... e.g.:
Debug.Print sr, sCell.Address(0, 0), _
srg1.Address(0, 0), srg2.Address(0, 0)
Else ' not equal to sCriteria (usually do nothing)
' e.g.:
Debug.Print sr, sCell.Address(0, 0), "Nope."
End If
Next sCell
End Sub
Have you tried using a for loop?
Eg:
For Each Cell in Range("B3:B8")
If Cell.Value = 1 Then
Set var1 = range("a3:aq3")
Else
Set var2 = range("a9:aq9")
End If
Next Cell

How to paste the data in a range where the starting row and column of the range is defined in a cell?

I have two sheets in my excel file:
Input Sheet: Sheet1
Target Sheet: Sheet2
What I want to achieve is to paste the value start from the column that I defined in cell C5 and also start from the row that I defined in cell C6. If the range defined by cell C5 and C6 already have data, then it will find the next empty row based on the column in cell C5 and paste the data in that empty row.
For example in the screenshot above, the starting column & row defined in cell C5 & C6 is B8, so the copied value will be pasted starting from cell B8 until E8. However, if the row already have data, then it will find the next empty row based on column B (which is B9) and paste it there.
I'm not sure how to modified my current script:
Public Sub CopyData()
Dim InputSheet As Worksheet ' set data input sheet
Set InputSheet = ThisWorkbook.Worksheets("Sheet1")
Dim InputRange As Range ' define input range
Set InputRange = InputSheet.Range("G6:J106")
Dim TargetSheet As Worksheet
Set TargetSheet = ThisWorkbook.Worksheets("Sheet2")
Const TargetStartCol As Long = 2 ' start pasting in this column in target sheet
Const PrimaryKeyCol As Long = 1 ' this is the unique primary key in the input range (means first column of B6:G6 is primary key)
Dim InsertRow As Long
InsertRow = TargetSheet.Cells(TargetSheet.Rows.Count, TargetStartCol + PrimaryKeyCol - 1).End(xlUp).Row + 1
' copy values to target row
TargetSheet.Cells(InsertRow, TargetStartCol).Resize(ColumnSize:=InputRange.Columns.Count).Value = InputRange.Value
End Sub
Any help or advice will be greatly appreciated!
Testing Scenario 1
Output of Testing Scenario 1
Please, try the next code:
Public Sub CopyData_()
Dim InputSheet As Worksheet: Set InputSheet = ThisWorkbook.Worksheets("Sheet1")
Dim InputRange As Range: Set InputRange = InputSheet.Range("G6:J106")
Dim arr: arr = InputRange.Value
Dim TargetSheet As Worksheet: Set TargetSheet = ThisWorkbook.Worksheets("Sheet2")
Dim TargetStartCol As String, PrimaryKeyRow As Long
TargetStartCol = TargetSheet.Range("C5").Value ' start pasting in this column in target sheet
PrimaryKeyRow = TargetSheet.Range("C6").Value ' this is the row after the result to be copied
Dim InsertRow As Long
InsertRow = TargetSheet.cells(TargetSheet.rows.Count, TargetStartCol).End(xlUp).row + 1
If InsertRow < PrimaryKeyRow Then InsertRow = PrimaryKeyRow + 1 'in case of no entry after PrimaryKeyRow (neither the label you show: "Row")
' copy values to target row
TargetSheet.cells(InsertRow, TargetStartCol).Resize(UBound(arr), UBound(arr, 2)).Value = arr
End Sub
Not tested, but if should work, I think. If something not clear or going wrong, please do not hesitate to mention the error, what it does/doesn't against you need or anything else, necessary to correct it.
Copy Data to Another Worksheet
Option Explicit
Sub CopyData()
Const sName As String = "Sheet1"
Const rgAddress As String = "G6:J106"
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = wb.Worksheets(sName)
Dim rg As Range: Set rg = ws.Range(rgAddress)
WriteCopyData rg
' or just:
'WriteCopyData ThisWorkbook.Worksheets("Sheet1").Range("G6:J106")
End Sub
Sub WriteCopyData(ByVal SourceRange As Range)
Const dName As String = "Sheet2"
Const dRowAddress As String = "C6"
Const dColumnAddress As String = "C5"
Dim rCount As Long: rCount = SourceRange.Rows.Count
Dim cCount As Long: cCount = SourceRange.Columns.Count
Dim dws As Worksheet
Set dws = SourceRange.Worksheet.Parent.Worksheets(dName)
Dim dRow As Long: dRow = dws.Range(dRowAddress).Value
Dim dCol As String: dCol = dws.Range(dColumnAddress).Value
Dim dfrrg As Range: Set dfrrg = dws.Cells(dRow, dCol).Resize(1, cCount)
Dim dlCell As Range
Set dlCell = dfrrg.Resize(dws.Rows.Count - dRow + 1) _
.Find("*", , xlFormulas, , xlByRows, xlPrevious)
If Not dlCell Is Nothing Then
Set dfrrg = dfrrg.Offset(dlCell.Row - dRow + 1)
End If
Dim drg As Range: Set drg = dfrrg.Resize(rCount)
drg.Value = SourceRange.Value
End Sub

How to paste on each cell while using For each cell loop

I have 2 columns A and B. I created a Sub loop to check if the value of cells in column 2 is <> "NULL" then if its not NULL I have to copy the valueof it and paste it to its counterpart row in Column A.
I tried this code but can't continue because I'm having a hard time pasting the value of the cell in column 2 to its left side column 1 counterpart it only paste in cell A2. How to paste it to every cell in the 1st column if the column 2 counterpart of it is not equal to NULL?
Sub IF_Loop()
Dim cell As Range
For Each cell In Range("TablePrac[Department]")
If cell.Value <> "NULL" Then
cell.Copy Range("A2")
End If
Next cell
End Sub
Copy Values in Excel Table
Before
After
The key difference between the two solutions is that the first 'deals' with the rows and columns of the worksheet, while the second uses the table (DataBodyRange) rows and columns (seems kind of more appropriate).
The 'cValue/CStr business' avoids the type mismatch error occurring if there is an error value.
Adjust the values in the constants section.
The Code
Option Explicit
Sub TableColumns()
Const wsName As String = "Sheet1"
Const dColString As String = "Table1[Column1]"
Const sColString As String = "Table1[Column2]"
Const sCriteria As String = "NULL"
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim ws As Worksheet: Set ws = wb.Worksheets(wsName)
Dim drg As Range: Set drg = ws.Range(dColString)
drg.ClearContents
Dim dCol As Long: dCol = drg.Column ' Worksheet Column
Dim srg As Range: Set srg = ws.Range(sColString)
Application.ScreenUpdating = False
Dim sCell As Range
Dim cValue As Variant
For Each sCell In srg.Cells
cValue = sCell.Value
If CStr(cValue) <> sCriteria Then
sCell.EntireRow.Columns(dCol).Value = sCell.Value ' Worksheet Row
End If
Next sCell
Application.ScreenUpdating = True
End Sub
Sub TableColumnsRowRange()
Const wsName As String = "Sheet1"
Const tblName As String = "Table1"
Const sColTitle As String = "Column2"
Const sCriteria As String = "NULL"
Const dColTitle As String = "Column1"
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim ws As Worksheet: Set ws = wb.Worksheets(wsName)
Dim tbl As ListObject: Set tbl = ws.ListObjects(tblName)
Dim sCol As Long: sCol = tbl.ListColumns(sColTitle).Index ' Table Column
Application.ScreenUpdating = False
Dim dCol As Long
With tbl.ListColumns(dColTitle)
.DataBodyRange.ClearContents
dCol = tbl.ListColumns(dColTitle).Index ' Table Column
End With
Dim srrg As Range
Dim cValue As Variant
For Each srrg In tbl.DataBodyRange.Rows ' Table (DataBodyRange) Row
cValue = srrg.Cells(sCol).Value
If CStr(cValue) <> sCriteria Then
srrg.Cells(dCol).Value = srrg.Cells(sCol).Value
End If
Next srrg
Application.ScreenUpdating = True
End Sub

Resources