Active VBA Macro that performs a vlookup to a separate sheet in the workbook - vba

I was asked to do this specifically not in the sheet itself within the cell.
I need a constantly running Macro so that when I put an ID number in cell D9 in sheet 1, various other cells in Sheet 1 get populated by data points in a table in Sheet 2.
I have the following:
Also, Excel is crashing constantly doing this, but my instruction is specifically to use VBA and not use normal lookups in the cell.
Tried setting it to general and other things. very new to VBA sorry
Private Sub Worksheet_Change(byVal Target As Range)
Dim ID As String
Dim LookupRange As Range
Set LookupRange = Sheet3.Range("A13:AN200")
Dim DataValue As String
If Sheets("Template").Range("D9").Value <> "" Then
ID = Sheets("Template").Range("D9")
DataValue = Application.WorksheetFunction.Vlookup(ID, LookupRange, 3, False)
Range("D11").Value = DataValue
End if
End

I reviewed your code and made some changes that should allow it to work. I have commented most of what I did. If you have questions please let me know.
Disclaimer: This is untested. So you will want to verify it before actually using it.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim wb As Workbook
Dim ws As Worksheet
Dim ws3 As Worksheet
Dim wsName As String
Dim IDRange As String
Dim ResultRange As String
Dim vLookUpRange As String
Dim ID As String
Dim LookupRange As Range
Dim DataValue As String
wsName = "Template"
IDRange = "D9"
ResultRange = "D11"
vLookUpRange = "A13:AN200"
'This is just a habbit of mine, I always set sheets to their own variables.
'It is just easier for me to work with
Set wb = ActiveWorkbook
Set ws = wb.Worksheets(wsName)
Set ws3 = wb.Worksheets(3)
'This line (moved from below Dim) was not writen correctly. it is not Sheet3 but sheets(3) As you can see I moved
'the sheet definition to above. (Again a habbit of mine)
Set LookupRange = ws3.Range(vLookUpRange)
'This is not needed but I add it when I am working with changes to sheets so that I only run the code I want
'when it is within the rang I am looking for. You could add logic to make sure that you only run the code if
'you are only modifying that spesific cell. But for your goal, I don't think it is needed.
If Not Intersect(Target, ws.Range(IDRange)) Is Nothing Then
'You can use .Value but .Value2 is slightly faster with very few consequences.
'eg if you ever need to read or write large amounts of data it will save you some time.
If ws.Range(IDRange).Value2 <> "" Then
ID = ws.Range(IDRange)
DataValue = Application.WorksheetFunction.VLookup(ID, LookupRange, 3, False)
'You also need to specify a sheet for this. Since this is located in the sheet you are entering
'data I assumed the sheet "template"
ws.Range(ResultRange).Value = DataValue
End If
End If
End Sub

Related

How to quickly switch what worksheet/workbook is being edited in VBA

Basically, I want my program to open a hyperlink to another workbook and copy a range of values onto my original workbook. The problem is, I don't know how to properly reference the workbook to "paste" onto
I've tried to replicate a lot of different internet examples. I've tried using "Set" and "With" to switch between them and I've tried to make the original workbook the active workbook before pasting and nothing has been working.
Private Sub findColumns_button_Click() 'userform code
Dim index As Integer, hyperlink_A As Variant, Wb As Worksheet, mainWorkbook As Variant
mainWorkbook = ActiveWorkbook.FullName
Worksheets("Data").Cells(2, 2) = ResultA_Combo.Value
index = findIndex(Cells(2, 2).Value)
hyperlink_A = findHyperlink(index)
Worksheets("Data").Cells(3, 2) = hyperlink_A
Workbooks.Open Filename:=hyperlink_A 'opens correctly
Dim test As Double
test = Worksheets("Data").Range("S23")
MsgBox test 'displays correct value from desired workbook
Workbooks.Activate Filename:=mainWorkbook 'not sure what to do here
End Sub
MsgBox test returns the desired value but I can't find a way to set a cell value in the original workbook equal to test
See if this helps, I've edited your code, and by comparing I hope you get in the right direction... see comments in code for more details:
Private Sub findColumns_button_Click() 'userform code
Dim index As Integer, hyperlink_A As Variant, Wb As Worksheet, mainWorkbook As Workbook
Dim wbSrc As Workbook
Set mainWorkbook = ActiveWorkbook
With mainWorkbook.Worksheets("Data")
.Cells(2, 2) = ResultA_Combo.Value
index = findIndex(.Value)
hyperlink_A = findHyperlink(index)
.Cells(3, 2) = hyperlink_A
End With
Set wbSrc = Workbooks.Open(Filename:=hyperlink_A) 'Allocate to variable and open at the same time
Dim test As Double
test = mainWorkbook.Worksheets("Data").Range("S23")
MsgBox test 'displays correct value from first workbook
mainWorkbook.Activate 'as long you fully qualify the ranges, you don't need and should avoid as much as possible to use .Activate & .Select
Dim test2 As Double
wbSrc.Worksheets(1).Range("A1") = mainWorkbook.Worksheets("Data").Range("S23") * 2
test2 = wbSrc.Worksheets(1).Range("A1")
MsgBox test2 'displays correct value from second workbook
End Sub

Copy Range to Another Worksheet Using Input Box to Choose Range

I am writing a VBA macro where I have an InputBox come up, the user will select a range which will be a full column, and then the macro will paste that range in a particular place on another worksheet. I have been trying to make this code work, but I keep getting different errors depending on what I try to fix, so I was wondering if someone could help me out. I have pasted the relevant parts of the code:
Sub Create_CONV_Files()
Dim NewCode As Range
Set NewCode = Application.InputBox(Prompt:="Select the column with the code numbers", Title:="New Event Selector", Type:=8)
Dim RawData As Worksheet
Set RawData = ActiveSheet
Dim OffSht As Worksheet
Set OffSht = Sheets.Add(After:=Sheets(Sheets.Count))
OffSht.Name = "offset.sac"
Worksheets(RawData).Range(NewCode).Copy _
Destination:=OffSht.Range("A:A")
End Sub
I have tried making the input a string instead, but I am also getting errors there and am not sure how to fix that. I was hoping to use roughly the method I have outlined as my full code has multiple destination sheets and ranges.
Thank you very much for any help you can offer!
once you have set a Range object it brings with it its worksheet property so there's no need to qualify its worksheet
Sub Create_CONV_Files()
Dim NewCode As Range
Set NewCode = Application.InputBox(prompt:="Select the column with the code numbers", title:="New Event Selector", Type:=8)
Dim OffSht As Worksheet
Set OffSht = Sheets.Add(After:=Sheets(Sheets.count))
OffSht.Name = "offset.sac"
NewCode.Copy _
Destination:=OffSht.Range("A1")
End Sub

Copy rows until the last row with value ONLY to another workbook

I was able to copy the rows to another workbook by using predefined ranges. However, I wanted to make sure that it only needs to copy those with values. I've been formulating this code but it returns an error -1004
Private Sub test()
Dim WBa As Workbook, MyPathA As String
Dim FinalRow As Long
Dim getDBsht As Worksheet
MyPathA = "sharepoint.com/Financial Tracker v8.xlsx"
ThisWorkbook.Sheets("ConTracker_DB").UsedRange.ClearContents
' Attempt to open a sharepoint file
Set WBa = Workbooks.Open(MyPathA)
'Set WBb = Workbooks.Open(MyPathB)
Set getDBsht = WBa.Sheets("ConTracker_DB")
getDBsht.UsedRange.Copy
'error starts here
ThisWorkbook.Sheets("ConTracker_DB").UsedRange.Paste
Application.CutCopyMode = False
WBa.Close
Set WBa = Nothing
End Sub
UPDATED CODE: UsedRange fixed my copy rows with value only, but pasting error still persists
You could iterate the individual cells and copy only those which have a value:
Dim sourceCell as Range
Dim targetCell as Range
Set targetCell = ThisWorkbook.Sheets("ConTracker_DB").Range("A1").
For each sourceCell in Range("theNamedRangeYouWantToCopyFrom")
'I'm not sure if you need a dynamic range to copy from, but if you don't...
'...it's much easier to use a "named range" for that.
If sourceCell.Value <> "" Then
targetCell.Value = sourceCell.Value
Set targetCell = targetCell.Offset(1,0)
End If
Next sourceCell
Try defining the final column you need copied and then defining the start and end cells in the range:
FinalCol = 23 '(or whatever you need)
getDBsht.Range(getDBsht.Cells(1, 1), getDBsht.Cells(FinalRow, FinalCol)).Copy
Also note that above I'm specifying which worksheet the cells in the range come from. This can help if you have multiple workbooks/worksheets open at once.
Defining the destination before you start copying is a good idea, too.
CopyTo = ThisWorkbook.Sheets("ConTracker_DB").Range("A1")
Answering my question :))
Basically if you're using usedRange.Copy
you should be pasting with
Cells(1, 1).PasteSpecial Paste:=xlPasteValues
Please find below for the complete code if you're using this:
Private Sub test()
Dim WBa As Workbook, MyPathA As String
Dim FinalRow As Long
Dim getDBsht As Worksheet
MyPathA = "sharepoint.com/Financial Tracker v8.xlsx"
ThisWorkbook.Sheets("ConTracker_DB").UsedRange.ClearContents
' Attempt to open a sharepoint file
Set WBa = Workbooks.Open(MyPathA)
'Set WBb = Workbooks.Open(MyPathB)
Set getDBsht = WBa.Sheets("ConTracker_DB")
getDBsht.UsedRange.Copy
ThisWorkbook.Sheets("ConTracker_DB").Cells(1, 1).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
WBa.Close
Set WBa = Nothing
End Sub

Copy the value from a cell in a worksheet into a range of cells

I'm intending to conduct a macro which will open up a workbook from the specified path, and loop through its worksheets which has the names "Januari, Februari, Mars" specifically, to deduct the value from C34. C34 has a value recorded there every time, so it shouldn't change. However I want to copy it to the current worksheet, where the first target should be at AA73, the second at AA74 etc. My code is
Sub Test()
Dim myHeadings
Dim i As Long
Dim path As String
path = "C:\pathtofile\file.xlsx"
Dim currentWb As Workbook
Set currentWb = ActiveWorkbook
Dim openWb As Workbook
Set openWb = Workbooks.Open(path)
Dim openWs As Worksheet
myHeadings = Array("Januari", "Februari", "Mars")
For i = 0 To UBound(myHeadings)
Set openWs = openWb.Sheets("&i")
currentWb.Sheets("Indata").Range("AA73+Application.Match(i,Array,False)").Value = openWs.Range("C34").Value
Next i
End Sub
However the compiler says that the subscript is out of range at the row with
Set openWs = openWb.Sheets("&i")
Here I've tried to do "i", i, &i among other things, but it haven't changed. Also I've tried to use "ThisWorkbook" instead of "ActiveWorkbook" but it didn't help either. Does anybody have an input as to how to achieve this in a more proper way?
EDIT: Adapting to the response from Dave, it works to import the sheets. However I get an error in:
currentWb.Sheets("Indata").Range("AA73+Application.Match(i,Array,False)").Value = openWs.Range("C34").Value
Where I get Automation Error -2147221080 (800401a8) at said code snippet.
You have already put your sheet names into an array, so you can just call the sheet name from the array as:
Set openWs = openWb.Sheets(myHeadings(i))

Excel VBA: Loop through cells and copy values to another workbook

I already spent hours on this problem, but I didn't succeed in finding a working solution.
Here is my problem description:
I want to loop through a certain range of cells in one workbook and copy values to another workbook. Depending on the current column in the first workbook, I copy the values into a different sheet in the second workbook.
When I execute my code, I always get the runtime error 439: object does not support this method or property.
My code looks more or less like this:
Sub trial()
Dim Group As Range
Dim Mat As Range
Dim CurCell_1 As Range
Dim CurCell_2 As Range
Application.ScreenUpdating = False
Set CurCell_1 = Range("B3") 'starting point in wb 1
For Each Group in Workbooks("My_WB_1").Worksheets("My_Sheet").Range("B4:P4")
Set CurCell_2 = Range("B4") 'starting point in wb 2
For Each Mat in Workbooks("My_WB_1").Worksheets("My_Sheet").Range("A5:A29")
Set CurCell_1 = Cells(Mat.Row, Group.Column) 'Set current cell in the loop
If Not IsEmpty(CurCell_1)
Workbooks("My_WB_2").Worksheets(CStr(Group.Value)).CurCell_2.Value = Workbooks("My_WB_1").Worksheets("My_Sheet").CurCell_1.Value 'Here it break with runtime error '438 object does not support this method or property
CurCell_2 = CurCell_2.Offset(1,0) 'Move one cell down
End If
Next
Next
Application.ScreenUpdating = True
End Sub
I've done extensive research and I know how to copy values from one workbook to another if you're using explicit names for your objects (sheets & ranges), but I don't know why it does not work like I implemented it using variables.
I also searched on stackoverlow and -obviously- Google, but I didn't find a similar problem which would answer my question.
So my question is:
Could you tell me where the error in my code is or if there is another easier way to accomplish the same using a different way?
This is my first question here, so I hope everything is fine with the format of my code, the question asked and the information provided. Otherwise let me know.
5 Things...
1) You don't need this line
Set CurCell_1 = Range("B3") 'starting point in wb 1
This line is pointless as you are setting it inside the loop
2) You are setting this in a loop every time
Set CurCell_2 = Range("B4")
Why would you be doing that? It will simply overwrite the values every time. Also which sheet is this range in??? (See Point 5)
3)CurCell_2 is a Range and as JohnB pointed it out, it is not a method.
Change
Workbooks("My_WB_2").Worksheets(CStr(Group.Value)).CurCell_2.Value = Workbooks("My_WB_1").Worksheets("My_Sheet").CurCell_1.Value
to
CurCell_2.Value = CurCell_1.Value
4) You cannot assign range by just setting an "=" sign
CurCell_2 = CurCell_2.Offset(1,0)
Change it to
Set CurCell_2 = CurCell_2.Offset(1,0)
5) Always specify full declarations when working with two or more objects so that there is less confusion. Your code can also be written as
Option Explicit
Sub trial()
Dim wb1 As Workbook, wb2 As Workbook
Dim ws1 As Worksheet, ws2 As Worksheet
Dim Group As Range, Mat As Range
Dim CurCell_1 As Range, CurCell_2 As Range
Application.ScreenUpdating = False
'~~> Change as applicable
Set wb1 = Workbooks("My_WB_1")
Set wb2 = Workbooks("My_WB_2")
Set ws1 = wb1.Sheets("My_Sheet")
Set ws2 = wb2.Sheets("Sheet2") '<~~ Change as required
For Each Group In ws1.Range("B4:P4")
'~~> Why this?
Set CurCell_2 = ws2.Range("B4")
For Each Mat In ws1.Range("A5:A29")
Set CurCell_1 = ws1.Cells(Mat.Row, Group.Column)
If Not IsEmpty(CurCell_1) Then
CurCell_2.Value = CurCell_1.Value
Set CurCell_2 = CurCell_2.Offset(1)
End If
Next
Next
Application.ScreenUpdating = True
End Sub
Workbooks("My_WB_2").Worksheets(CStr(Group.Value)).CurCell_2.Value
This will not work, since CurCell_2 is not a method of Worksheet, but a variable. Replace by
Workbooks("My_WB_2").Worksheets(CStr(Group.Value)).Range("B4").Value