Linking multiple Excel documents to an Access DB - sql

I have ~200 Excel workbooks each with a unique name, in its own folder, something like C:\docs\daily\XXXX\XXXX_Daily_Report_20150920.xls, where XXXX is just an alphanumeric identifier and the date is obviously just today's date.
I need to get one cell (the same cell, "I2") from all 200+ Excel workbooks every single day.
I know you can link Excel workbooks to Access but I can't figure out a way to make it link to a different workbook each day and I'm wondering if there is a query to simply get that one cell instead of linking the entire Excel workbook.
Right now I have Excel VBA that opens each Excel file and copies and pastes it into the corresponding row/column in my workbook...but since it does this 200+ times I'm wondering if Access will have a faster solution.
Is there any way to write a query/macro in Access that will link the cell I2 from each day's new report (so tomorrow's would be "XXXX Daily Report 20150921.xls") and just populate a table with XXXX in the first column and the value of I2 in the second?

Function import()
source_date = InputBox("date (yyyymmdd)")
Set db = CurrentDb()
db.Execute ("delete * from [DailyData]")
Set app = CreateObject("Excel.Application")
Set FSO = CreateObject("Scripting.FileSystemObject")
Set folder_list = FSO.GetFolder("C:\docs\daily").subfolders
For Each Fldr In folder_list
Source = Fldr.Name
SourceFile = "c:\docs\daily\" & Source & "\" & Source & "_daily_reports_" & source_date & ".xlsm"
Set WB = app.workbooks.Open(SourceFile)
amount = WB.sheets("sheet1").range("I2").Value
SQL = "Insert into [DailyData] (source, amount) select '" & Source & "'," & amount
db.Execute (SQL)
WB.Close
Next Fldr
MsgBox ("done")
End Function
This takes all the files for a specific date and puts the input into a table called DailyData, with fields for Source and Amount.
Note - modified 9/22 to eliminate the inside loop and If block - this assumes every folder will have a file for the current day's update. If not, you may want to verify that the file exists before you try to open it.

Related

VBA Error on opening workbook - Cannot find workbook that is there

I'm attempting to open a workbook, but Excel gives me an error message saying that it cannot find the workbook.
Dim pricing As Workbook
dim fname As String
fname = Dir(ActiveWorkbook.Path & "\Budget Pricing Detail*.csv")
Set pricing = Workbooks.Open(Filename:=fname, UpdateLinks:=False)
As you can see I'm using a wildcard to pull the file name as the last bit of the filename will be different for each instance. What's weird to me as that when Excel gives me the error box it actually names the WHOLE file (even though I never did in my code) I want it to find and says it can't find it. Also what's weird is that this was working already and all of a sudden now it isn't.
I think DIR only returns the filename, and not the entire path. Try:
fname = ActiveWorkbook.Path & "\" & Dir(ActiveWorkbook.Path & "\Budget Pricing Detail*.csv")

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

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)"

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

Write the content of two Excel files in a third one

I'm very new to vba programming and I would like to know what is the best method to do the following operation : read data from two Excel files (from a particular column of each file) and write this data in a third Excel file, writing the data contained in the first file first then the data contained in the second file. The figure below illustrates what I want to do :
How can I do that on click on a command button, without opening the two first files (I mean I don't want the user to see them).
You need to make so
Workbooks.Open Filename:= "c:\myfile\FILE1.xls"FILE1.xls"
Workbooks.Open Filename:= "c:\myfile\FILE2.xls"
After you open the FILE1.xls and FILE.xls you can create or open FILE3.xls,
in this case we create the FILE3.xls
Dim wb As Workbook
Set wb = Workbooks.Add
After this you read the data in FILE1.xls and FILE2.xls, you can read with WHILE or other LOOP or you read with COPY and PASTE data in new file.
In this case we see the LOOP strategy.
Dim i as Integer
Dim value as String
i=0
value = value = Workbooks("FILE1.xls").Worksheets("sheet1")..Range("B:B").Cells(i, 1)
Workbooks("FILE1.xls").Worksheets("sheet1").Activate
while value <> ""
Workbooks("FILE1.xls").Worksheets(2).Range("A:A").Cells(i, 1) = value
value = value = Workbooks("FILE1.xls").Worksheets("sheet1")..Range("B:B").Cells(i, 1)
Wend
Repeat ste for "FILE2.xls" read data and write in "FILE3.xls"
and at the and you close
wb.SaveAs "c:\myfile\"FILE3.xls""
wb.Close
And close the read data file
Workbooks("FILE1.xls").Close
Workbooks("FILE2.xls").Close

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