Vlookup to a table on a different user selected file VBA Macro - vba

I am trying to enter a Vlookup formula into Column S of a worksheet named "FY_16". I need the user to select the file (which changes each month) that the "table array" for the formula is in.
Each month the file changes, but the column I want to look up to will always be the same - Column W (but have varying number of rows). The "table array" that the formula will look up to is part of a table.
My code at this point is below:
Private Function UseFileDialogOpen()
MsgBox ("When the browse window opens: please select the previous months published FY16 Consulting SKU File")
Dim myString As String
' Open the file dialog
With Application.FileDialog(msoFileDialogFilePicker)
.AllowMultiSelect = False
.Show
If .SelectedItems.Count = 1 Then
myString = .SelectedItems(1)
'MsgBox myString
UseFileDialogOpen = myString
Else
MsgBox ("Failed to properly open file")
myString = "fail"
UseFileDialogOpen = myString
End If
End With
End Function
Sub Vlookup
Dim filelocation 'as what?????
filelocation = UseFileDialogOpen()
Worksheets("FY_16").Range("T2:T" & LastRow).FormulaR1C1 = "=vlookup(RC[-3], [" & myString & "] PA Rev!R1C23:R900000C23,1,false)"
My issue occurs on the final line of code. I receive a "run time error 1004 : application defined or object defined" message.
I know my syntax is incorrect for the vlookup in a few ways. I am not sure the "& myString & " is correct, perhaps this should be "filelocation"?
I also don't believe R1C1 can be used to name a range like I have in the vlookup. I typically would use
.Range(Cells(2,23), Cells(90000,23))
But I am not sure how to use that with the variable that holds the selected file name.
Also, I am using the 90000 row because this will go past my data each month (usually row count is around 75000). I would much rather find the exact row number but I don't believe this can be done without opening the "target file" selected by the user. If there is a way to achieve this, please offer any advice!
I am wondering if there is a way to use the Table Names to set the table array?
The non-VBA vlookup is as follows:
=VLOOKUP(Q2,'TargetFile.xlsb'!REV[[#All],[Net New Match]],1,FALSE)
TargetFile is the user selected file
REV is the worksheet the table array is on
Net New Match is the column I want to look up to (the entire column)
I played around with using these table names but couldn't get the syntax correct (possibly because the rest of the formula code is incorrect also).
Any help will be greatly appreciated. Let me know if any clarification is needed.
Mike

The correct syntax for accessing a range in an unopened workbook would be something that looks like 'C:\Temp\[Book2.xlsx]PA Rev'!R1C23:R900000C23. That won't be the same format that comes from the UseFileDialogOpen function.
You also can't use myString within your Vlookup subroutine because you defined that variable to be local to UseFileDialogOpen - but you can use filelocation which you have used to store the result from UseFileDialogOpen. But, as I said, it won't be in the right format anyway, so it will require a bit of reformatting.
The following command should do the necessary reformatting:
Worksheets("FY_16").Range("T2:T" & LastRow).FormulaR1C1 = _
"=vlookup(RC[-3],'" & Left(fileLocation, InStrRev(fileLocation, "\")) & _
"[" & Mid(fileLocation, InStrRev(fileLocation, "\") + 1) & _
"]PA Rev'!R1C23:R90000C23,1,false)"

Related

Workbook variable name from drop down box

I have 10 workbooks with near identical names "???????? Service Planner.xlsm" where ???????? is a place name. They all have identical tab names and identical column headers. Instead of going into the files 1 by 1 i'd like to have a seperate file that will lookup the information that i need. I'd like to have a drop down box with the "????????" part of the file name, when selected the correct file would open and my seperate file would populate by using vlookup.
I've used worksheet change before and have target.value as a sheet name, i thought i could do the same and use it as part of the workbook name but no matter what i try i can't get it to work. Can anyone give me some tips or point me in the right direction?
Below is the formula i use when it's different sheets i want to look up.
With Range("F5:L" & lRow)
.Formula = "=IF($C5=""Night"",VLOOKUP($A5,'\\server\drive name\Folder\[filename.xlsm]" & Target.Value & "'!$A:$I,F$1,0)
.Value = .Value
End With
Any help would be appreciated.
If you make a specific custom function, excluding some part of the name of your application, it could look like this:
Option Explicit
Sub TestMe()
Debug.Print getApplicationName(" Service Planner.xlsm - Excel")
End Sub
Public Function getApplicationName(nameToExclude As String) As String
Dim length As Long
length = Len(Application.Caption) - Len(" Service Planner.xlsm - Excel")
getApplicationName = Left(Application.Caption, length)
End Function
The property used is Application.Caption which returns the whole name of the file + - Excel at the end.

Button to add column?

In excel 2013 I was hoping if someone can make a code for adding 1 blank column to a spreadsheet based on the user input after they click this button that is an activex control. The column will end based on how many rows there are in my table, meaning if there are 10 rows I should not see a column on line 11 of the spreadsheet.
I keep getting an error saying application defined or object error after I put in the column I want to add, I even tried both caps an lowercase and the same error comes up.
Private Sub CommandButton2_Click()
Dim x As String
x = InputBox("Enter a column that you want to add: ", "What column?")
If x = "" Then Exit Sub
ColumnNum = x
Columns(ColumnNum & ":" & ColumnNum).Insert shift:=xlShiftRight
Columns(ColumnNum - 1 & ":" & ColumnNum - 1).Copy Range("A1" & ColumnNum)
Columns(ColumnNum & ":" & ColumnNum).ClearContents
End Sub
This will get you started:
Dim x As Variant
Dim ColumnNum%
x = InputBox("Enter a column that you want to add: ", "What column?")
If x = "" Then Exit Sub
ColumnNum = x
ThisWorkbook.Sheets("Sheet1").Columns(ColumnNum).Insert shift:=xlRight
ThisWorkbook.Sheets("Sheet1").Columns(ColumnNum - 1).Copy
'THe line above doesnt make any sense whatsoever.
'Im not going to try and trouble shoot it but it seems like you dont understand how to
' properly scuplt things. Youll notice i changed how you strucutred the .copy part.
'THe part that doesnt make sense to me is the Range section.
ThisWorkbook.Sheets("Sheet1").Columns(ColumnNum).ClearContents
There were a few things wrong with your code.
You need to put Option Explicit at the top of your code. You didnt declare your variables.
you inpout box needs to be declared as variant
When i played around with this its clear you didnt fully reference what columns in what sheets need to be inserted. Notice my "ThisWorkbook....."
Your if statement is structured incorrectly as well.
I suggest you spend some time reading up on the basics some more :)

How to pull data into excel from access?

I have an excel worksheet that has two sheets. On the first one i have the printable page and the second sheet is for the first to pull data from using vlookup. The second sheet consists of 8 columns. The first column is the ID that's being used by vlookup on the first page. The second is for first/last name. What i want to do is to make excel search for this (first/last name) in an access database and then retrieve and fill 3 other columns from the data in access. There are 2 tables that i want it to look into. It will find the name in either one of them and there are no duplicates. Does anyone have any idea how i might achieve this? Thanks!
You have a few choices. One is to use an .ODC using "Data-Get External Data". If you go through the wizard you can store the search criteria in the external data link (and if desired save this as an .ODC file). If you record a Macro when doing this, you will see where you can alter the recorded VBA code to substitute your own criteria from Excel (e.g, First/Lame name).
Another way, if your data isn't too big is to bring in a single sheet with "Data-GetExternalData" containing all your data then use VLookup (or index/match) to just retrieve the appropriate names. This works well when your database is not too big to bring entirely into Excel, efficiently.
But I use the following code because it's slick and doesn't require exposing any connection info (including passwords) in the .ODC (stored external data link). It's also faster. In this example, I use ADO because it's a SQL/Server database, but if the data is in Access (.ACCDB or MDB) then you can use ordinary DAO. If you need the ADO, don't forget to include the ADO library in your references.
In my example, I used a date range to find the data I wanted. In your case, it would be Lname and Fname instead of a date range.
This Excel VBA code is what I use.
Sub RefreshReport()
On Error GoTo Err_Handler
verrevent = "RefreshReport"
Dim rs As New ADODB.Recordset
If cn.State = 0 Then OpenNewConnection
Dim xlRange As Excel.Range
'Delete prior data
Range("MyTargetTable").EntireRow.Delete
'Call sproc to fetch member match
'This uses SPROC, but could be any SQL statement passing search criteria from Excel
vsql = "sproc_my_procedure '" & Range("BegDate") & "' ,'" & Range("EndDate") & "'"
'Call sproc to fetch member match
Set xlRange = Range("MyTargetDataSheet!A2")
Set rs = cn.Execute(vsql)
xlRange.Cells.CopyFromRecordset rs
'Refresh a pivot table if you have one
Set pt = Sheets("Summary").PivotTables("PivotTable1")
pt.RefreshTable
MsgBox ("Refresh Complete")
Exit_Proc:
Exit Sub
Err_Handler:
MsgBox ("Refresh program error. Please snip and send." & vbCrLf & vbCrLf & "Err " & Err.Number & " " & verrevent & " " & vbCrLf & Err.Description & vbCrLf)
Resume Exit_Proc
End Sub

Transpose, match, and Import standard Excel form into Excel Database

I am new to VBA but I am working on setting up a Database in Excel (I realize that Access is much better suitedm but I am doing this for someone else).
I have a source file that has information in the range B5:B17, this form will be for others to send to the person managing the database. I need to write a VBA code that will select the data in the source range, transpose it, find a match is one exists, then either overwrite the existing data or add to the next blank row. Here is the sequence:
Prompts the database manager to open the source file (I know how to do this)
Transpose the data in B5:B17
Search for a match in cell B7 (source file) and match it to values in column C (database)
Overwrite the matching data
If no match exists, then write to the next empty row.
I have been using the following code as a guide but it has some limitations. The source file has to be open, also, I am not sure how to include the Transpose function to this code. Any help id appreciated
This should do what you are looking for.
Sub Sample()
Dim rngEnteredID As Range
Dim lngRowWithMatch As Range
Set rngEnteredID = Sheets("Sheet1").Range("B7")
On Error GoTo NoMatch
lngRowWithMatch = WorksheetFunction.Match(rngEnteredID.Value, Sheets("Sheet2").Range("C:C"), 0)
On Error GoTo 0
Sheets("Sheet2").Range("A" & lngRowWithMatch & ":K" & lngRowWithMatch).Value = Application.Transpose(Sheets("Sheet1").Range("B5:B17"))
Exit Sub
NoMatch:
Dim lngEmptyRow As Long
lngEmptyRow = Sheets("Sheet2").Cells(Rows.Count, 3).End(xlUp).Row + 1
Sheets("Sheet2").Range("A" & lngEmptyRow & ":K" & lngEmptyRow).Value = Application.Transpose(Sheets("Sheet1").Range("B5:B17"))
End Sub

Split a cell's formulaic elements into seperate cells

So I have a cell with the formula =A+B, A and B are external values for which the external spreadsheet is no longer open. I was wondering if excel remembers the formula elements and if it was possible to get those element values into other cells. i.e.
Row Formula Value
1 =A+B 45
2 =ELEMENT(A1, 1) 10
3 =ELEMENT(A1, 2) 35
I can't imagine it being that simple though? I could seperate out the formula in vba using the + as a pivot, but this is not ideal as it would require the external spreadsheet to be reopened. If the external spreadsheet has to be reopened then I needn't bother trying to seperate the formula in the first place. I hope this makes sense and has an answer.
Your formula is already accessing those values in order to sum them in the open workbook. You do NOT need to re-open the workbook in order to evaluate the reference values, nor to parse the formula in the active workbook.
Assuming your formula references a closed workbook, with a simple sum function like:
='C:\Users\david_zemens\Desktop\[test.xlsx]Sheet1'!$A$1 + ='C:\Users\david_zemens\Desktop\[test.xlsx]Sheet1'!$B$1
You can parse the formula either in VBA or using string functions on the worksheet. As you note, for this example, parsing by the + operator will suffice. Since I think you understand how to do this, my example does not demonstrate how to parse the formula.
As long as you know or can obtain the references from the formula, you should be able to access those cells' values via formula, or programmatically in VBA using ExecuteExcel4Macro.
Sub GetValsFromClosedWorkbook()
Dim fileName As String
Dim filePath As String
Dim sheetName As String
Dim cellref As String
Dim myFormula As String
'This example might be one of the two arguments in your "A+B" formula:
' 'C:\Users\david_zemens\Desktop\[test.xlsx]Sheet1'!A1
'## Assume you can properly parse the formula to arrive at these:
fileName = "test.xlsx"
filePath = "C:\Users\david_zemens\Desktop\"
sheetName = "Sheet1"
cellref = "A1"
'Concatenate in to R1C1 notation
myFormula = "='" & filePath & "[" & fileName & "]" & sheetName & "'!" & _
Range(cellref).Address(, , xlR1C1)
'## First, demonstrate that we can evaluate external references:
With Range("B1")
.Value = myFormula
MsgBox .Value
.Clear
End With
'## Evaluate the formula using ExecuteExcel4Macro:
MsgBox ExecuteExcel4Macro(Replace(myFormula, "=", vbNullString))
End Sub
Additional info
http://spreadsheetpage.com/index.php/tip/a_vba_function_to_get_a_value_from_a_closed_file/
Update
Based on OP's question of how this works (comments, below), I am not certain of how it works behind the scenes but here is my guess/explanation:
Firstly, keep in mind that a cell may have various properties like .Text, .Value, .Value2, .Formula etc. which in one way or another represent its contents.
The values aren't in the active file until the formula is evaluated, at which point Excel queries the external file and returns the current Value at that reference. Now the active file contains that Value as well as a Formula reference the external file.
As you continue working the active file preserves the Value and the reference, but may only update the value when prompted. For example, when you re-open the linked workbook, you will be prompted whether to "update external links".
if you say no, it will use the previously stored values (still preserves the Formula, it just doesn't evaluate it.
if you say yes, it will re-evaluate the formula (in case the value in the external file has changed) and return the new .Value
So, that's what I suspect is happening. If you're asking "How does Excel access the data inside an un-opened workbook" I don't really know how I just know that it does.