HLOOKUP-VBA in loop for specified Range - excel

I want to do lookup in a specified range(rows X to AF in "main" tab[Sheet1]) which I am doing using VBA hlookup function. The problem I am facing is that I am not able to do this lookup in a loop, which means once the hlookup is done in X2:AF2, then it should do the calculation in X3:AF3 for next row.
I need to do this because the Tablehandle[sheeet2] result will change every time (macro will clear this sheet) and the headers will not in order.
So can someone help me to get hlookup in a loop for a specified row?
My "Main" sheet
"TableHandle" sheet
Option Explicit
Sub hlookup1()
Dim i, r As Long
For i = 1 To Range("K100000").End(xlUp).Row - 1
'first macro will get the table inside sheet ...
Sheets("TableHandle").Select
'Range("A2").Select
'Range(Selection, Selection.End(xlDown)).Select
'Range("A2:B10").Select
'Selection.Copy
Range("F1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=True
'hlookup
Sheets("Main").Select
Range("X2").Select
Range("X" & i + 1).Select
ActiveCell.FormulaR1C1 = "=HLOOKUP(R1C,TableHandle!R1C6:R2C14,2,0)"
Selection.Copy
Range("X2:AF2").Select 'PROBLEM from Here, it will again calculate in x2 to af2 range)
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Cells.Replace What:="#N/A", Replacement:="", LookAt:=xlPart, SearchOrder _
:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
i = i + 1
Next
End Sub

Yours is a good idea but in practice it has a number of drawbacks as demonstrated by the error handling you had planned. I think you would also have to replace the formulas you insert with so much effort with the values they produce. Please try this code instead. It transfers data from the TableHandler sheet to the Main without the use of worksheet formulas.
Sub hlookup1()
' 211
Dim Data As Variant ' source data
Dim Headers As Range ' column captions in 'Main'
Dim Fnd As Range ' Find the column caption
Dim Rs As Long ' Row: Source (= 'Data')
Dim Cs As Long ' Column: Source
Dim Rt As Long ' Row: Target
Dim Ct As Long ' Column: Target
'first macro will get the table inside sheet ...
With Worksheets("TableHandle") ' data source
Rs = .Cells(.Rows.Count, "A").End(xlUp).Row
Data = .Range(.Cells(2, "A"), .Cells(Rs, "X")).Value
' Row 1 of 'Data' holds the column headers because
' SheetRow(2) became the ArrayRow(1)
End With
Application.ScreenUpdating = False ' speed up execution
With Worksheets("Main")
Set Headers = .Range("A2:X2")
' start in array row 2 because array row 1 holds the column captions
For Rs = 2 To UBound(Data) ' loop through all rows
Rt = .Cells(.Rows.Count, "A").End(xlUp).Row + 1
For Cs = 1 To UBound(Data, 2) ' loop through the columns of each row
Set Fnd = Headers.Find(Data(1, Cs), LookIn:=xlValues, lookat:=xlWhole)
If Not Fnd Is Nothing Then ' skip column not found
.Cells(Rt, Fnd.Column).Value = Data(Rs, Cs)
End If
Next Cs
Next Rs
End With
Application.ScreenUpdating = True
End Sub
If a column in the TableHandler should not be found the macro will not transfer data, leaving the target column blank. If you want a warning it would have to be added. There is a little confusion in your question as to rows and columns. Should I have guessed wrongly here or there I trust you will be able to make the required modifications. However, you are welcome to ask for help, too.

it was important and i spent all day to make this possible, i ans my question here.
the code is shortned as below, it works fast and efficient. thanks for suggestions!
Dim Hlookp As Variant
Hlookp = Application.HLookup(Range("B1:J1").Value, Sheets("TableHandle").Range("F1:N" & Cells(Rows.Count, 1).End(xlUp).row), 2, False)
Range("B" & i + 1 & ":J" & i + 1).Value = Hlookp

Related

Excel Cannot Paste all copied cells

So I have around 16.000 cells to copy from one column to another one. If I copy paste it, only the first 1000 cells get pasted, the lower i get in the sheet, the less cells get pasted.
I cannot move & replace the column itself aswell since I m getting the error "This can`tbe done on a multiple range selection".
How can I copy all the cells at once? Thanks in advance
So i solved it over a looped vba:
'
' Macro3 Macro
'
' Keyboard Shortcut: Ctrl+ΓΌ
'
For i = 1 To 36430
Range("L" & i).Select
Selection.Copy
Range("M" & i).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Next i
End Sub```
I don't understand why you would use a loop here so maybe I'm missing something. Additionally When moving data in vba it's faster to move arrays than to copy/paste the data. e.g. something like this should be faster:
Sub CopySelection()
Dim addr As String, ArrToCopy, TargetCell As String, Rw As Long, Cl As Long
addr = selection.Areas(1).Address(False, False)
ArrToCopy = Sheet1.Range(addr).Value2
TargetCell = InputBox("What is the target StartCell?") 'e.g. B5
Cl = Range(TargetCell).Column
Rw = Range(TargetCell).Row
With Sheet1
.Range(.Cells(Rw, Cl), .Cells(Rw - 1 + UBound(ArrToCopy, 1), Cl - 1 + UBound(ArrToCopy, 2))).Value2 = ArrToCopy
End With
End Sub
hope this helps.

Convert all IF formulas (TRUE) into values except the rows containing an IF formula (FALSE)

I am interested in doing this: IF Cell C14 = Cell $C$8, THEN keep the cell value BUT remove the IF formula. For rest of the Cells in Column C with IF Formula (False condition: "InsertText!"), retain the IF formula
Refer to Image here
I've tried multiple ways of phrasing the VBA syntax but I'm not getting the desired result.
Sub convertToValue()
Dim totRow As Long
Dim rng As Range
' Find row with word InsertText in it
totRow = Cells.Find(What:="InsertText", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Row
Set rng = Rows("C:C")
rng.Copy
rng.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, Transpose:=False
ActiveSheet.Paste
Application.CutCopyMode = False
End Sub
Is there a way to do this? Thanks!
This works for me with my test spreadsheet.
Sub convertToValue()
LastRow = ActiveCell.SpecialCells(xlLastCell).Row
' change the 13 in the line below to whichever row the data
' actually starts on (the one after the table header)
For Row = 13 To LastRow
Set CurrentCell = Range("C" & Row)
' do the copy/paste only if the current cell is a
' formula AND it doesn't evaluate to "Insert Text"
If Left(CurrentCell.Formula, 1) = "=" And CurrentCell.Value2 <> "Insert Text" Then
Range("C8").Copy
CurrentCell.PasteSpecial Paste:=xlPasteValues
End If
Next
Range("C3").Select
End Sub
If you assign it to a button then you can set the product, enter new details, push the button, and repeat.

Find value in table then copy values in different columns to a different table

I have a table in Sheet1 of a workbook and several rows of the table will have #N/A as their value of column N. I would like to find a way to have a vba macro find all rows that have #N/A in column N then copy the values from column M and L of those rows to the bottom of another table on Sheet2 of the same workbook.
ActiveSheet.ListObjects("SEC_Data").Range.AutoFilter Field:=14, Criteria1:= _
"#N/A"
Range("M88343:M88351").Select
Selection.Copy
Sheets("LKUP_Client Name").Select
Range("B2").Select
Selection.End(xlDown).Select
Range("B" & ActiveCell.Row + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("company_2018 thru2019_gim").Select
Range("L88343:L88351").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("LKUP_Client Name").Select
Range("C").Select
Selection.End(xlDown).Select
Range("C" & ActiveCell.Row + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
The way I would approach this is to first iterate through column N on sheet 1, when #N/A found then copy the cells and paste in corresponding location on sheet 2. Something like the below:
Sub CopyProcedure()
Dim i As Long
Dim lRow1 As Long, lRow2 As Long
Dim wsSheet1 As Worksheet, wsSheet2 As Worksheet
Set wsSheet1 = Sheets("Sheet 1")
Set wsSheet2 = Sheets("Sheet 2")
lRow1 = wsSheet1.Range("N" & wsSheet1.Rows.Count).End(xlUp).Row
'assuming your data starts in the first row
'iterate to the last row of column n
For i = 1 To lRow1
'look for the #N/A text
If wsSheet1.Range("N" & i).Text = "#N/A" Then
'adjust this to suit which column in sheet 2 you need
lRow2 = wsSheet2.Range("A" & wsSheet2.Rows.Count).End(xlUp).Row + 1
'when text found copy required cells
wsSheet1.Range("L" & i, "M" & i).Copy
'paste cell values in required location on sheet 2
'NOTE THIS WILL PASTE IN THE LAST ROW SPECIFIED ON SHEET 2 AND IN COLUMN A
'adjust as you see fit
wsSheet2.Range("A" & lRow2).PasteSpecial xlPasteValues
'empty clipboard
Application.CutCopyMode = False
End If
Next i
Set wsSheet1 = Nothing
Set wsSheet2 = Nothing
End Sub
This is by no means the most efficient way to do it, but I am sure it will get the job done if I understand your problem correctly.
Also, caveat, I haven't tested or debugged this. :)

Search for next empty cell

I want to copy data in certain cells to another sheet in a table.
My code copies the data and searches for the cell to be pasted to. If there is a value in the destination cell, it is looped to check the subsequent rows in the same column until it finds an empty cell.
If there's 2000 rows of data currently in the table, it will search all 2000 cells before landing in the 2001st row.
The amount of time taken to execute the code is affected by the size of the table.
Is there any way to execute faster?
Below is a sample, its copying data from two cells.
Sub Test()
Sheets("Sheet1").Select
Range("K10").Select
Selection.Copy
Sheets("Table").Select
Range("A2").Select
Do While Not (ActiveCell.Value = "")
ActiveCell.Offset(1, 0).Activate
Loop
Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
Sheets("Sheet1").Select
Range("G15").Select
Selection.Copy
Sheets("Table").Select
Range("B2").Select
Do While Not (ActiveCell.Value = "")
ActiveCell.Offset(1, 0).Activate
Loop
End sub
Try following sub.
Sub CopyPaste()
Dim sht1, sht2 As Worksheet
Set sht1 = Worksheets("Sheet1")
Set sht2 = Worksheets("Table")
sht1.Range("K10").Copy sht2.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
sht1.Range("G15").Copy sht2.Cells(Rows.Count, 2).End(xlUp).Offset(1, 0)
End Sub
It's unclear on whether you expect to find interim blank cells within the worksheet's used range or whether you expect to always put the new values at the bottom of the used range. This should work for both scenarios.
Sub Test()
Dim ws1 As Worksheet
Set ws1 = Worksheets("sheet1")
With Worksheets("table")
'force a definition for a .UsedRange on the worksheet
.Cells(.Rows.Count, "A") = Chr(32)
.Columns(1).SpecialCells(xlCellTypeBlanks).Cells(1) = ws1.Cells(10, "K").Value
.Columns(1).SpecialCells(xlCellTypeBlanks).Cells(1) = ws1.Cells(15, "G").Value
'clear the artificial .UsedRange
.Cells(.Rows.Count, "A").Clear
'Debug.Print .UsedRange.Address(0, 0)
End With
End Sub

Copy and Paste row values into next empty row

I am trying to copy the same row of information from a sheet called "Report" (numbers will change), and paste the values into a sheet "Data" that has headers in the first row.
I tried piecing together some code from various questions.
Here is my code:
Sub Insert_Data()
'
' Insert_Data Macro
Sheets("Report").Range("B9:F9").Copy
Sheets("Data").Range("A1").PasteSpecial Paste:=xlPasteValues,
Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
Sub PSData_Transfer()
Sheets("Report").Range("B9:F9").Copy
Dim lastrow As Long
lastrow = Sheets("Data").Range("A65536").End(xlUp).Row
Sheets("Data").Activate
Cells(lastrow + 1, 1).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
End Sub
You may have to modify this a little bit to work with your code, but feel free to use mine that I'm using in my current worksheet and it works perfect!
Sub Insert_Data()
For R = LR To 2 Step -1 ' Change the 2 in "To 2" to the row just below your header,
' but typically row 2 is the second cell under header anyways
Call CopyTo(Worksheets(2).Range("B" & R & ":C" & R), Worksheets(1)Range("A:B"))
Next R
End Sub
Private Function CopyTo(rngSource As Range, rngDest As Range)
LR = rngDest.cells(Rows.Count, 1).End(xlUp).row
rngDest.cells(LR + 1, 1).value = rngSource.cells(1, 1).value
rngDest.cells(LR + 1, 2).value = rngSource.cells(1, 2).value
End Function
I don't like to use the copy method as it's slow and it likes to copy all the extra jargin, where as getting the value is much faster and it's retrieving ONLY the value

Resources