VBA VLookup in Loop - vba

I´m trying to do a VLOOKUP of a column data set at a Sheet called "SyS" in G column. and I'd like to Vlookup relevant data using columns in another sheet called "CONF_mapping", located in the same Workbook. I need to find my data located at the range ("A1:E65000") (It's at column A, but I need to retrieve data from other columns with my vlookup to SyS). I'm not getting good results with my code, and I beg your pardon, it´s my first question in the forum.
Worksheets("SyS").Select
Dim wsThis As Worksheet
Dim aCell As Range
Sheets("CONF_mapping").Columns(2).Copy Destination:=Sheets("SyS").Columns(8)
Set wsThis = Sheets("SyS")
With wsThis
For Each aCell In .Range("A1:E65000")
'.Cells(aCell.Row, 8) = "Not Found"
On Error Resume Next
.Cells(aCell.Row, 8) = Application.WorksheetFunction.VLookup( _
aCell.value, wsThat.Range("G2:G65000"), 2, False)
On Error GoTo 0
Next aCell
End With
Worksheets("SyS").Select
I have find this code but I was not able to make it works for me.
I would appreciate any help.

You have mistake here:
VLookup(aCell.value, wsThat.Range("G2:G65000"), 2, False)
Range "G2:G65000" Have just 1 column G, but you try to get column#2 which does not exists.
UPD:
I guess you need something like this:
Const COLUMN_TO_MATCH_IN_SYS = 8
Const COLUMN_TO_MATCH_IN_CONF = 1
Sub test()
Dim wsSys As Worksheet
Dim wsConf As Worksheet
Set wsSys = Sheets("SyS")
Set wsConf = Sheets("CONF_mapping")
Dim RowSys As Range
Dim RowConf As Range
For Each RowSys In wsSys.UsedRange.Rows
For Each RowConf In wsConf.UsedRange.Rows
If RowSys.Cells(1, COLUMN_TO_MATCH_IN_SYS) = _
RowConf.Cells(1, COLUMN_TO_MATCH_IN_CONF) Then
' Copy row values which is needed
RowSys.Cells(1, 6) = RowConf.Cells(1, 1) ' From column A(conf) to G(sys)
RowSys.Cells(1, 7) = RowConf.Cells(1, 2) ' From column B(conf) to H (sys)
End If
Next aCell
Next
End Sub
With this solution you don't need to search the Range for each cell (just for each row), so it will work 5 times faster.

Related

Using cell references for autoshape line

Have a sheet with a list of Cell references in two columns.
Trying to create a macro that pulls these into a range and uses the first cell in column A for the start point of an autoshape line and the second cell in column B as the end point of an autoshape line.
The script is working and doing what I want it to however at the end of execution I am getting "Subscript out of range error"
What am I doing wrong?
rng = Range("A1:B100")
Worksheets("Map").Activate
For Each row In rng
i = i + 1
ActiveSheet.Shapes.AddConnector(msoConnectorStraight, Range(rng(i, 1)).Left, Range(rng(i, 1)).Top, Range(rng(i, 2)).Left, Range(rng(i, 2)).Top).Select
Next row
Avoid select and activate, declare all the variables and loop only from the rows of the range:
Sub TestMe()
Dim rng As Range
Set rng = Worksheets("Map").Range("A1:B100")
Dim row As Range
Dim i As Long
For Each row In rng.Rows
i = i + 1
Worksheets("Map").Shapes.AddConnector msoConnectorStraight, _
row.Cells(i, 1).Left, _
row.Cells(i, 1).Top, _
row.Cells(i, 2).Left, _
row.Cells(i, 2).Top
Next row
End Sub
How to avoid using Select in Excel VBA
The Range("A1:B100") has no connection to Worksheets("Map") beyond a possible coincidence that Worksheets("Map") was the active worksheet. Provide proper parent worksheet reference.
You Set objects like ranges to their vars.
Don't Select the connectors you create; not in a loop, not ever.
with Worksheets("Map")
set rng = .Range("A1:B100")
For Each row In rng
i = i + 1
.Shapes.AddConnector msoConnectorStraight, _
.Range(rng(i, 1)).Left, .Range(rng(i, 1)).Top, _
.Range(rng(i, 2)).Left, .Range(rng(i, 2)).Top
Next row
end with

Copy values from Range and paste each one with different given (row) offset in another sheet

First of all I would like to introduce myself. Iam Miguel and I recently started to learn VBA in order to improve and save time at work. I am familiar with formulas, all types, but when turning to VBA I get sometimes stuck.
I am trying to loop the range A2:A355 from Sheet"Aux" and copy each value to sheet "CS", and each value shall be pasted in Column A:A, but with the offset given in range B2:B355 Sheet "Aux". For Example I give the example attached.
Sample Code:
This is the code:
Sub cablexsection()
Dim s As Integer
Dim smax As Integer
smax = Sheets("Aux").Range("b1").Value
Sheets("CS").Activate
For s = 3 To smax
Sheets("CS").Cells(s, 1).Value = Sheets("Aux").Cells(s, 1).Value
'here I have to set the offset to down in order to paste cells given Sheets("Aux").Cells(s, 2) values
Next s
End Sub
And under the link you can find the file to be worked in:
Original File
Thank you very much and sorry if this question is repeated. I have tried to look through the forum but maybe I do not know what to write exactly.
Try this
Option Explicit
Sub CableXsection()
Dim wsAux As Worksheet, wsCS As Worksheet
Dim s As Long, sMax As Long, offSetCell As Range
Set wsAux = ThisWorkbook.Worksheets("Aux")
Set wsCS = ThisWorkbook.Worksheets("CS")
sMax = wsAux.Range("B1").Value
Application.ScreenUpdating = False
For s = 3 To sMax
Set offSetCell = wsAux.Cells(s, 2) '2 is the offset column from the same row
If Not IsError(offSetCell) And IsNumeric(offSetCell) Then
wsCS.Cells(offSetCell.Value2 + s, 1).Value = wsAux.Cells(s, 1).Value
End If
Next
Application.ScreenUpdating = True
End Sub

Quicker way to filter out data based on a particular value

I am working with a workbook that currently has 3 sheets. The first sheet is an overview where the filtered data will appear. Cell D11 has the color that I am looking for. Upon entering the color cells F3:I27 Populate with information like color, shape, number and animal.
C2C-Tracker2
I would use a Pivot Table for this, however, I have another set of data in K3:M27. This data is pulled from another sheet within the workbook with a similar function.
The formula that I am using is:
=IFERROR(INDEX(cases!A:A,SMALL(IF(EXACT($D$3,cases!$C:$C),ROW(cases!$C:$C)-ROW($F$1)+1),ROW(1:1))),"")
Of course it is entered using CTRL + SHIFT + ENTER for it to work properly.
I tried using a VBA Macro that I pulled from the video below:
Excel VBA Loop to Find Records Matching Search Criteria
So many array formulas can really make your workbook very slow.
Here is a code to populate Dataset1 using arrays. It runs in less than a second.
Hope this gets you started. I have commented the code but if you still have a problem understanding, just post back :)
Sub Sample()
Dim DSOne() As String
Dim tmpAr As Variant
Dim wsCas As Worksheet: Set wsCas = ThisWorkbook.Sheets("Cases")
Dim wsMain As Worksheet: Set wsMain = ThisWorkbook.Sheets("Sheet1")
Dim lRow As Long, i As Long, j As Long
'~~> Check if user entered a color
If wsMain.Range("D3").Value = "" Then
MsgBox "Please enter a color first", vbCritical, "Missing Color"
Exit Sub
End If
'~~> Clear data for input in main sheet
wsMain.Range("F3:F" & wsMain.Rows.Count).ClearContents
'~~> Get last row of Sheet Cases
lRow = wsCas.Range("A" & wsCas.Rows.Count).End(xlUp).Row
With wsCas
'~~> Get count of cells which have that color
i = Application.WorksheetFunction.CountIf(.Columns(3), wsMain.Range("D3").Value)
'~~> Check if there is any color
If i > 0 Then
'~~> Define your array to hold those values
ReDim DSOne(1 To i, 1 To 4)
'~~> Store the Sheet Cases data in the array
tmpAr = .Range("A1:D" & lRow).Value
j = 1
'~~> Loop through the array to find the matches
For i = LBound(tmpAr) To UBound(tmpAr)
If tmpAr(i, 3) = wsMain.Range("D3").Value Then
DSOne(j, 1) = tmpAr(i, 1)
DSOne(j, 2) = tmpAr(i, 2)
DSOne(j, 3) = tmpAr(i, 3)
DSOne(j, 4) = tmpAr(i, 4)
j = j + 1
End If
Next i
'~~> write to the main sheet in 1 Go!
wsMain.Range("F3").Resize(UBound(DSOne), 4).Value = DSOne
End If
End With
End Sub
Screenshot:
Using the above approach now populate Dataset2 :)

Fill down column according to colum in another sheet

I've been a longtime viewer of this place and I love it! I've never needed to post because I've been able to find everything. However, today I am stumped and I cannot find an answer here so forgive me if this has been addressed.
The question is this:
I want to copy ColumnA (starting say, A2) from SHEET1 into ColumnB (starting B8) of SHEET2.
My problem is that the source column (SHEET1:ColumnA) has a dynamic number of rows every instance the workbook is used. I also do not want to fill down to the end of the sheet or display zeros etc.
I perceive this as a filldown problem but sourcing from another sheet. Though I may be wrong about that and cannot make it work myself.
Thanks very much in advance.
Try this:
sub copyToOtherSheet()
dim startRowASht1 as int
dim startRowSht2 as int
dim loopr as Boolean
dim counter as long
loopr = True
counter = 0
startRowSht1 = 2
startRowSht2 = 8
Do While loopr = True
Worksheets("Sheet2").Range("B" & Cstr(startRowSht2 + counter)).value = Worksheets("Sheet1").Range("A" & Cstr(startRowSht2+counter)).value
if Cstr(worksheets("Sheet1").Range("A" & Cstr(startrowsht2 + counter)).value) = "" then
loopr = False 'you reached an empty cell and it stops copying
else
counter = counter + 1
end if
End Sub
Public Sub a()
With Sheets("Sheet2")
.Range(.Cells(2, 1), .Cells(.Rows.Count, 1).End(xlUp)).Copy Destination:=Sheets("Sheet1").Cells(8, 2)
End With
End Sub
If you are willing to use a macro:
Sub copyRange()
Dim rSource As Range
Set rSource = Range(Sheet1.Cells(2, 1), Sheet1.Cells(Sheet1.Rows.Count, 1).End(xlUp))
Range(Sheet2.Cells(8, 2), Sheet2.Cells(Sheet2.Rows.count,2)).Clear
Range(Sheet2.Cells(8, 2), Sheet2.Cells(7 + rSource.Rows.Count, 2)).Value = rSource.Value
End Sub
This assumes that there is nothing below the contiguous range of values in column A on Sheet1, and that in Sheet2 you want to completely clear out whatever is in column B from row 8 down to the bottom. (If your range in column A of Sheet1 gets smaller from one invocation to the next, you don't want to leave any remnants in Sheet2)

How to compare two columns in different sheets

I have one excel file with multiple sheets.
I need to compare two sheets (1) TotalList and (2) cList with more than 25 columns, in these two sheets columns are same.
On cList the starting row is 3
On TotalList the starting row is 5
Now, I have to compare the E & F columns from cList, with TotalList E & F columns, if it is not found then add the entire row at the end of TotalList sheet and highlight with Yellow.
Public Function compare()
Dim LoopRang As Range
Dim FoundRang As Range
Dim ColNam
Dim TotRows As Long
LeaData = "Shhet2"
ConsolData = "Sheet1"
TotRows = Worksheets(LeaData).Range("D65536").End(xlUp).Row
TotRows1 = Worksheets(ConsolData).Range("D65536").End(xlUp).Row
'TotRows = ThisWorkbook.Sheets(LeaData).UsedRange.Rows.Count
ColNam = "$F$3:$F" & TotRows
ColNam1 = "$F$5:$F" & TotRows1
For Each LoopRang In Sheets(LeaData).Range(ColNam)
Set FoundRang = Sheets(ConsolData).Range(ColNam1).Find(LoopRang, lookat:=xlWhole)
For Each FoundRang In Sheets(ConsolData).Range(ColNam1)
If FoundRang & FoundRang.Offset(0, -1) <> LoopRang & LoopRang.Offset(0, -1) Then
TotRows = Worksheets(ConsolData).Range("D65536").End(xlUp).Row
ThisWorkbook.Worksheets(LeaData).Rows(LoopRang.Row).Copy ThisWorkbook.Worksheets(ConsolData).Rows(TotRows + 1)
ThisWorkbook.Worksheets(ConsolData).Rows(TotRows + 1).Interior.Color = vbYellow
GoTo NextLine
End If
Next FoundRang
NextLine:
Next LoopRang
End Function
Please help with the VBA code.
Thanks in advance...
First I am going to give some general coding hints:
set Option Explicit ON. This is done through Tools > Options >
Editor (tab) > Require Variable Declaration . Now you HAVE to
declare all variables before you use them.
always declare a variables type when you declare it. If you are unsure about what to sue or if it can take different types (not advisable!!) use Variable.
Use a standard naming convention for all your variables. Mine is a string starts with str and a double with dbl a range with r, etc.. So strTest, dblProfit and rOriginal. Also give your variables MEANINGFUL names!
Give your Excel spreadsheets meanigful names or captions (caption is what you see in excel, name is the name you can directly refer to in VBA). Avoid using the caption, but refer to the name instead, as users can change the caption easily but the name only if they open the VBA window.
Ok so here is how a comparison between two tables can be done with your code as starting point:
Option Explicit
Public Function Compare()
Dim rOriginal As Range 'row records in the lookup sheet (cList = Sheet2)
Dim rFind As Range 'row record in the target sheet (TotalList = Sheet1)
Dim rTableOriginal As Range 'row records in the lookup sheet (cList = Sheet2)
Dim rTableFind As Range 'row record in the target sheet (TotalList = Sheet1)
Dim shOriginal As Worksheet
Dim shFind As Worksheet
Dim booFound As Boolean
'Initiate all used objects and variables
Set shOriginal = ThisWorkbook.Sheets("Sheet2")
Set shFind = ThisWorkbook.Sheets("Sheet1")
Set rTableOriginal = shOriginal.Range(shOriginal.Rows(3), shOriginal.Rows(shOriginal.Rows.Count).End(xlUp))
Set rTableFind = shFind.Range(shFind.Rows(5), shFind.Rows(shFind.Rows.Count).End(xlUp))
booFound = False
For Each rOriginal In rTableOriginal.Rows
booFound = False
For Each rFind In rTableFind.Rows
'Check if the E and F column contain the same information
If rOriginal.Cells(1, 5) = rFind.Cells(1, 5) And rOriginal.Cells(1, 6) = rFind.Cells(1, 6) Then
'The record is found so we can search for the next one
booFound = True
GoTo FindNextOriginal 'Alternatively use Exit For
End If
Next rFind
'In case the code is extended I always use a boolean and an If statement to make sure we cannot
'by accident end up in this copy-paste-apply_yellow part!!
If Not booFound Then
'If not found then copy form the Original sheet ...
rOriginal.Copy
'... paste on the Find sheet and apply the Yellow interior color
With rTableFind.Rows(rTableFind.Rows.Count + 1)
.PasteSpecial
.Interior.Color = vbYellow
End With
'Extend the range so we add another record at the bottom again
Set rTableFind = shFind.Range(rTableFind, rTableFind.Rows(rTableFind.Rows.Count + 1))
End If
FindNextOriginal:
Next rOriginal
End Function