[AccessD] Pulling Data from Excel into Access with "Automation"

William Benson (VBACreations.Com) vbacreations at gmail.com
Thu Jun 30 17:42:59 CDT 2011


You can set a reference to Excel in the Access vba project, or use late
binding. Assuming you have set a reference you can use code, it's pretty
easy. My recent project is to look for sheets in open files (or let the user
open other filed), and populate combo boxes with workbook names, worksheet
names, and column headers. 

Caveats:  Methods like Union ()  need xl.Union to be invokable. Same with
Intersection, and Selection. It's hard to remember this. Trust me. Painful.
If you use late binding you need values for all intrinsic constants. You
also have to watch out for version changes and the impact on intrinsic
constants.


On a Access form I have these objects.

cmdNewWB
combo0  - holds workbook names and # sheets that have data (based on row 1)
combo2  -  holds worksheet names and number of data columns (based on filled
columns)
lstFields  -  holds field names  (row headers in each column)

Then play with the combos after the form launches. 

Option Compare Database
Option Explicit
Dim m_b_XLLaunched As Boolean
Dim m_b_OpeningWorkbook As Boolean
Dim bAfterUpdateCombo0Fired As Boolean
Dim bAfterUpdateCombo2Fired As Boolean
Private Function GetSelectedFile(Optional ExtensionStringWithPipeSeparator)
As String
Dim iFileTypes  As Long
Dim fDialog As Office.FileDialog
Dim varFile As Variant
Dim strTypes As String
Dim strFilters As String
Dim strTemp As String
Dim strParseThis As String
Dim ItemsSkipped()
Dim strSkipped As String
Dim i As Long

strFilters = ""
strTypes = ""
ReDim ItemsSkipped(0)
If Not IsMissing(ExtensionStringWithPipeSeparator) Then
  strParseThis = CStr(ExtensionStringWithPipeSeparator)
Else
  strParseThis = "*.*"
End If
  
If strParseThis <> "*.*" Then
  Do Until InStr(strParseThis, "|") = 0
    strTemp = Left(strParseThis, InStr(strParseThis, "|") - 1)
    strParseThis = Mid(strParseThis, Len(strTemp) + 2)
    strTemp = Replace$(strTemp, "*.", "")
    UpdateFilterAndType strTypes:=strTypes, strFilters:=strFilters,
strTemp:=strTemp, ItemsSkipped:=ItemsSkipped
  Loop
  strTemp = Replace$(strParseThis, "*.", "")
  UpdateFilterAndType strTypes:=strTypes, strFilters:=strFilters,
strTemp:=strTemp, ItemsSkipped:=ItemsSkipped

Else
  strTypes = strTypes & ";*.*"
  strFilters = strFilters & ",All Files"
End If

If UBound(ItemsSkipped) > 0 Then
  strSkipped = ""
  For i = 1 To UBound(ItemsSkipped)
    strSkipped = strSkipped & Chr(13) & "'" & ItemsSkipped(i) & "'"
  Next
  strSkipped = Mid(strSkipped, 2)
  MsgBox "Known file Type List not comprehensive enough to accommodate
extension(s):" & Chr(13) & Chr(13) & strSkipped
End If
If strTypes <> "" Then
  Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
  fDialog.AllowMultiSelect = False
  fDialog.Title = "Select a file to examine"
  fDialog.Filters.Clear
  fDialog.Filters.Add Mid(strFilters, 2), Mid(strTypes, 2)
  If fDialog.Show <> True Then
    MsgBox "You clicked Cancel in the file dialog box."
    GoTo Exit_Me
  Else
    Set varFile = fDialog.SelectedItems
    GetSelectedFile = varFile(1)
  End If
Else
  MsgBox "No Accepted File Types Were Specified!", vbInformation
  GetSelectedFile = ""
  
End If
Exit_Me:


End Function


Private Sub cmdNewWB_Click()
Dim xl As Excel.Application
Dim strFile As String
Dim FSO As FileSystemObject
Dim wb As Excel.Workbook
Dim ws As Excel.Worksheet
Dim Col1 As New Collection
Dim Col2 As New Collection




'MakeThisSheetCSV GetXL.ActiveWorkbook.ActiveSheet
'End
Set xl = GetXL

strFile = GetSelectedFile("xl*")
On Error Resume Next
Set wb = xl.Workbooks.Open(strFile)
If Not wb Is Nothing Then
  m_b_OpeningWorkbook = True
  PopulateWBCombo FindThis:=wb.Name
End If


On Error GoTo 0

Exit_Me:

End Sub
Function PopulateWBCombo(Optional FindThis)
Dim xl As Excel.Application
Dim wb As Excel.Workbook
Dim ws As Worksheet
Dim CountDataSheets As Long
Dim i As Long

Set xl = GetXL
Combo0.RowSourceType = "Value List"
Combo0.RowSource = ""
Combo0.Requery

For Each wb In xl.Workbooks
  If wb.Windows(1).Visible Then
    CountDataSheets = 0
    For Each ws In wb.Worksheets
      If LastRow(, , ws) > 1 Then
        If xl.WorksheetFunction.CountA(ws.Rows(1)) > 0 Then
          CountDataSheets = CountDataSheets + 1
        End If
      End If
    Next
    If CountDataSheets > 0 Then
      Combo0.AddItem wb.Name & ";" & CountDataSheets
    Else
      If m_b_OpeningWorkbook Then
        MsgBox "'" & wb.Name & "' has no data sheets ... closing it",
vbInformation
        wb.Close savechanges:=False
      End If
    End If
  End If
Next

If Not IsMissing(FindThis) Then
  Combo0.Value = Combo0.Column(0, Combo0.ListCount - 1)
  If Not bAfterUpdateCombo0Fired Then
    Call Combo0_AfterUpdate
  End If
Else
  Combo0.Value = Combo0.Column(0, 1)
  If Not bAfterUpdateCombo0Fired Then
    Call Combo0_AfterUpdate
  End If
End If
bAfterUpdateCombo0Fired = False
End Function
Function PopulateWSCombo()
Dim strFile As String
Dim ws As Excel.Worksheet
Dim wb As Excel.Workbook
Dim xl As Excel.Application

Set xl = GetXL

Combo2.RowSourceType = "Value List"
Combo2.RowSource = ""
Combo2.Requery

lstFields.RowSourceType = "Value List"
lstFields.RowSource = ""
lstFields.Requery

If Combo0.ListCount > 0 Then
  If Combo0.ListIndex <> -1 Then
    On Error Resume Next
    Set wb = xl.Workbooks(Combo0.Column(0, Combo0.ListIndex))
    If Not wb Is Nothing Then
      For Each ws In wb.Worksheets
        If LastRow(, , ws) > 1 Then
          If xl.WorksheetFunction.CountA(ws.Rows(1)) > 0 Then
            Combo2.AddItem ws.Name & ";" &
xl.WorksheetFunction.CountA(ws.Rows(1)) & " Cols"
          Else
          End If
        End If
      Next
    Else
      MsgBox "Workbook '" & Combo0.Column(0, Combo0.ListIndex) & "' no
longer open", vbInformation
      PopulateWBCombo xl
    End If
  End If
End If
If Combo2.ListCount > 0 Then
  Combo2.Value = Combo2.Column(0, 0)
  If Not bAfterUpdateCombo2Fired Then
    Call Combo2_AfterUpdate
  End If
Else
  Combo2.Value = ""
  If Not bAfterUpdateCombo2Fired Then
    Call Combo2_AfterUpdate
  End If
End If
bAfterUpdateCombo2Fired = False
End Function
Private Sub PopulateDataColumnList()
Dim wb As Excel.Workbook
Dim ws As Worksheet
Dim CountDataSheets As Long
Dim i As Long
Dim cell As Object
Dim xl As Excel.Application

Set xl = GetXL

lstFields.RowSourceType = "Value List"
lstFields.RowSource = ""
lstFields.Requery

If Combo2.ListIndex <> -1 And Combo0.ListIndex <> -1 Then
  On Error Resume Next
  If Not xl Is Nothing Then
    Set wb = xl.Workbooks(Combo0.Column(0, Combo0.ListIndex))
    If Not wb Is Nothing Then
      Set ws = wb.Worksheets(Combo2.Column(0, Combo2.ListIndex))
      If Not ws Is Nothing Then
        For Each cell In ws.Range(ws.Cells(1, 1), ws.Cells(1,
ws.Columns.Count).End(-4159))
          If Not IsEmpty(cell) Then
            lstFields.AddItem cell
          End If
        Next
      End If
    End If
  End If
End If


End Sub

Private Sub cmdRefresh_Click()
Call Form_Load
End Sub

Private Sub Combo0_AfterUpdate()
PopulateWSCombo
bAfterUpdateCombo0Fired = True
End Sub
  Private Sub Combo2_AfterUpdate()
  PopulateDataColumnList
  bAfterUpdateCombo2Fired = True
  End Sub
Private Sub Form_Load()
PopulateWBCombo
End Sub
Function GetXL() As Excel.Application
On Error Resume Next

  Set GetXL = GetObject(, "Excel.Application")
  If GetXL Is Nothing Then
    m_b_XLLaunched = False
    Set GetXL = CreateObject("Excel.Application")
    If GetXL Is Nothing Then
      MsgBox "Cannot create instance of Excel - aborting"
      GoTo Exit_Me
    Else
      m_b_XLLaunched = True
    End If
  Else
    m_b_XLLaunched = False
  End If
GetXL.Visible = True
AppActivate "Microsoft Access"
Exit_Me:
  Exit Function
End Function

Function MakeThisSheetCSV(WKS1 As Excel.Worksheet)
Dim WB1 As Excel.Workbook
Dim xl As Excel.Application
Set xl = WKS1.Application
Set WB1 = WKS1.Parent
WKS1.Copy

WKS1.UsedRange.Copy
'WS2.Range(WS1.UsedRange.Address).Select
xl.ActiveWorkbook.ActiveSheet.Range(WKS1.UsedRange.Address).Select
xl.ActiveWorkbook.ActiveSheet.Paste
On Error Resume Next
Kill Environ("Temp") & "\tempcsv.csv"
xl.ActiveWorkbook.SaveAs FileName:=Environ("Temp") & "\tempcsv.csv",
FileFormat:=6
xl.ActiveWorkbook.Close savechanges:=False  'closes csv

End Function





More information about the AccessD mailing list