将Access表数据复制到Excel工作表

将Access表数据复制到Excel工作表,excel,vba,ms-access,Excel,Vba,Ms Access,我正在尝试将Access数据库中的表复制到名为“ALL”的Excel工作表中。这张纸还是空白的 数据被追加到名为“count”的工作表中,其中有一个透视表 我花了三天时间研究这个问题,但没有找到解决办法 ' This function is used to calculate the number of rows Function lastrow() As Long Dim ix As Long ix = ActiveSheet.UsedRange.row

我正在尝试将Access数据库中的表复制到名为“ALL”的Excel工作表中。这张纸还是空白的

数据被追加到名为“count”的工作表中,其中有一个透视表

我花了三天时间研究这个问题,但没有找到解决办法

     ' This function is used to calculate the number of rows
     Function lastrow() As Long
     Dim ix As Long
     ix = ActiveSheet.UsedRange.row - 1 + ActiveSheet.UsedRange.Rows.count
     lastrow = ix
     End Function
     
     Sub Macro1()
     '
     ' Macro1 Macro
      ' change the path where you want to save the workbooks
     
     Dim Path As String
     Path = ThisWorkbook.Path & "\"
     
     Dim main_w As String
     Dim data_file As String
     Dim new_wb As String
     Dim created As Integer
     Dim dept As Range
     Dim adviser As Range
     Dim MJRL_COLN_NUM As Integer
     Dim Counter As Integer
     Dim rw As Range
     Dim curCell As Range
     Dim Cell As Range
     Dim nextCell As Range
     
     'Path = "U:\Macros\Adviser Macro\"
     
     main_w = ThisWorkbook.Name
     
     data_file = Workbooks.Open(Path + "data_file.xls").Name
     
     created = 1
     
     For Each dept In Columns(1).Cells
         If (dept.Text = "") Then GoTo 1
     '    MsgBox (dept.Text)
     
         If (created = 1) Then new_wb = Workbooks.Add.Name
             
         Windows(main_w).Activate    'activate the workbook
         
         Sheets("Sheet1").Select
         
         Cells.Select
         Selection.AutoFilter
         Selection.AutoFilter Field:=60, Criteria1:=dept.Text
         
         Range("A1").Select
         Range(Selection, Selection.End(xlToRight)).Select
         Range(Selection, Selection.End(xlDown)).Select
         Selection.Copy
         
         created = 0
             
         If (ActiveWindow.RangeSelection.Rows.count < 4000) Then
         
             Windows(new_wb).Activate
             ActiveSheet.Name = "ALL"
             ActiveSheet.Paste
         
         Cells.Select
         Selection.RowHeight = 12.75
         Cells.EntireColumn.AutoFit
         
         'sort records by dept, then by adv_name, then by id
         ActiveSheet.Range("A2").Sort Key1:=ActiveSheet.Range("BH1"), _
                                      Key2:=ActiveSheet.Range("BI1"), _
                                      Key3:=ActiveSheet.Range("C1"), _
                                      Header:=xlYes
         
                     
             '''''''''''''''''''''''''''''''''''''''''''
             Windows(data_file).Activate
             
             
             For Each adviser In Columns(2).Cells
                 If (adviser.Text = "") Then GoTo 2
                 'MsgBox adviser.Text
                 
                 Windows(new_wb).Activate
                 
                 Cells.Select
                 Selection.AutoFilter
                 Selection.AutoFilter Field:=61, Criteria1:=adviser.Text
       
                 
                 Range("A1").Select
                 Range(Selection, Selection.End(xlToRight)).Select
                 Range(Selection, Selection.End(xlDown)).Select
                 Selection.Copy
                    
                 If (ActiveWindow.RangeSelection.Rows.count < 1500) Then
                 
                     Sheets.Add
                     ActiveSheet.Name = adviser.Text
                     ActiveSheet.Paste
                     'Sort the records according to major, class, then ID
                     ActiveSheet.Range("A2").Sort Key1:=ActiveSheet.Range("BH1"), _
                                                  Key2:=ActiveSheet.Range("BI1"), _
                                                  Key3:=ActiveSheet.Range("C1"), _
                                                  Header:=xlYes
                                                  
                     'place the neccessary borders (seperators)
                     '31 is the number of the Major_code column
                     MJRL_COLN_NUM = 31
                     Counter = 2
                     For Each rw In ActiveSheet.Rows
                          Set curCell = ActiveSheet.Cells(Counter, MJRL_COLN_NUM)
                          
                          If (curCell.Value = "") Then GoTo 3
                           
                          Set nextCell = ActiveSheet.Cells(Counter + 1, MJRL_COLN_NUM)
                          If curCell.Value <> nextCell.Value Then
                             'add a line border*************************
                             Set Cell = ActiveSheet.Cells(Counter, 1)
                             Range(Cell, Cell.End(xlToRight)).Borders(xlEdgeBottom).Weight = xlMedium
                          End If
                          Counter = Counter + 1
                     Next
             
     3:      Cells.Select
             Selection.RowHeight = 12.75
             Cells.EntireColumn.AutoFit
             Range("A1").Select
             ActiveWorkbook.Sheets("ALL").Activate
     
                 End If
             Next
     2:
             ActiveWorkbook.Sheets("ALL").Activate
             Cells.Select
             Selection.AutoFilter
             Range("A1").Select
     
     
             ' This sub will add the sheet Count to each workbook it will simply copy paste from
             ' the pivot table of the adviser distribution
             
             Dim rngend As Long
             Dim n As Long
             Dim row As Integer
             Dim row_total As Integer
             Dim str As String
             n = 3
             
             ' Activating the count sheet
             
             Windows("adviser counts (1 & 2).xls").Activate
             Sheets("Sheet3").Select
             
             ' Selecting the Department Column
             ActiveSheet.Cells(3, 1).Select
             
             
             rngend = lastrow() - 1
      
             Do While n < rngend
                 
                 If ActiveCell.Value = dept.Text Then
                     row = n
                 End If
                    
                 
                 If ActiveCell.Value = dept.Text & " Total" Then
                     row_total = n
                     'If ActiveCell.Value = "UPP Total" Then
                     '    MsgBox row_total
                     'End If
                 End If
                 
             'MsgBox row_total
             n = n + 1
             ActiveCell.Offset(1, 0).Select
             Loop
             
             ActiveSheet.Rows("1:2").Select
             Selection.Copy
             
             ' need to change to appropriate files
             
             Windows(new_wb).Activate
              Dim A2 As Integer
             A2 = 20
             For A2 = 0 To A2 Step 1
             If SheetExists("Sheet:" & A2) Then
             Sheets("Sheet:" & A2).Select
             Exit For
             End If
             Next
             
             ActiveSheet.Cells(1, 1).Select
             ActiveSheet.Paste
             
             Windows("adviser counts (1 & 2).xls").Activate
             Sheets("Sheet3").Select
             
            
             ActiveSheet.Rows(row & ":" & row_total).Select
             Selection.Copy
             
             Windows(new_wb).Activate
             
             Dim A1 As Integer
             A1 = 20
             For A1 = 0 To A1 Step 1
             If SheetExists("Sheet:" & A2) Then
             Sheets("Sheet:" & A2).Select
             Exit For
             End If
             Next
             
             ActiveSheet.Name = "count"
             ActiveSheet.Cells(3, 1).Select
             ActiveSheet.Paste
             Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
             SkipBlanks:=False, Transpose:=False
             
             Sheets("count").Select
             Sheets("count").Move Before:=Sheets(2)
             
             
             Sheets("ALL").Select
             Sheets("ALL").Move Before:=Sheets(1)
              
             
             ActiveWorkbook.SaveAs (Path & dept.Text)
             ActiveWorkbook.Close
             
                 
             created = 1
         End If
         
         Windows(main_w).Activate
         
         
     Next
     1:
     
     Windows(data_file).Close
     
     '
     End Sub
     
     
     Function SheetExists(sheetName As String) As Boolean
     Dim wk As Worksheet
     On Error Resume Next
     Set wk = ActiveWorkbook.Sheets(sheetName)
     SheetExists = Not (wk Is Nothing)
     Set wk = Nothing
     On Error GoTo 0
     End Function
     
”此函数用于计算行数
函数lastrow()的长度为
只要
ix=ActiveSheet.UsedRange.row-1+ActiveSheet.UsedRange.Rows.count
lastrow=ix
端函数
亚宏观1()
'
'宏1宏
'更改要保存工作簿的路径
将路径设置为字符串
路径=此工作簿。路径&“\”
变暗主缆(如字符串所示)
Dim data_文件作为字符串
将新的\u wb变暗为字符串
创建为整数的Dim
Dim dept As系列
像射程一样变暗
Dim MJRL_COLN_NUM作为整数
作为整数的Dim计数器
变暗rw As范围
Dim curCell As范围
暗淡单元格作为范围
Dim nextCell As范围
'Path=“U:\Macros\advisor Macro\”
main_w=此工作簿。名称
数据文件=工作簿。打开(路径+“数据文件.xls”)。名称
已创建=1
对于第(1)列中的每个部门。单元格
如果(dept.Text=“”),则转到1
'MsgBox(部门文本)
如果(created=1),则为new_wb=Workbooks.Add.Name
Windows(主窗口)。激活“激活工作簿”
图纸(“图纸1”)。选择
单元格。选择
自动筛选
Selection.AutoFilter字段:=60,Criteria1:=dept.Text
范围(“A1”)。选择
范围(选择,选择。结束(xlToRight))。选择
范围(选择,选择。结束(xlDown))。选择
选择,复制
已创建=0
如果(ActiveWindow.RangeSelection.Rows.count<4000),则
Windows(新建)。激活
ActiveSheet.Name=“全部”
活动表。粘贴
单元格。选择
Selection.RowHeight=12.75
Cells.EntireColumn.AutoFit
'按部门、按adv_名称、按id对记录进行排序
ActiveSheet.Range(“A2”).Sort键1:=ActiveSheet.Range(“BH1”)_
键2:=ActiveSheet.Range(“BI1”)_
键3:=ActiveSheet.Range(“C1”)_
标题:=xlYes
'''''''''''''''''''''''''''''''''''''''''''
Windows(数据文件)。激活
第(2)列中的每个顾问。单元格
如果(advisor.Text=“”),则转到2
'MsgBox advisor.Text
Windows(新建)。激活
单元格。选择
自动筛选
Selection.AutoFilter字段:=61,Criteria1:=advisor.Text
范围(“A1”)。选择
范围(选择,选择。结束(xlToRight))。选择
范围(选择,选择。结束(xlDown))。选择
选择,复制
如果(ActiveWindow.RangeSelection.Rows.count<1500),则
表。添加
ActiveSheet.Name=advisor.Text
活动表。粘贴
'根据专业、班级和ID对记录进行排序
ActiveSheet.Range(“A2”).Sort键1:=ActiveSheet.Range(“BH1”)_
键2:=ActiveSheet.Range(“BI1”)_
键3:=ActiveSheet.Range(“C1”)_
标题:=xlYes
'放置必要的边界(分隔符)
'31是主代码列的编号
MJRL_COLN_NUM=31
计数器=2
对于ActiveSheet.Rows中的每个rw
设置curCell=ActiveSheet.Cells(计数器,MJRL\u COLN\u NUM)
如果(curCell.Value=“”),则转到3
Set nextCell=ActiveSheet.Cells(计数器+1,MJRL\u COLN\u NUM)
如果curCell.Value nextCell.Value,则
'添加线条边框*************************
设置单元格=ActiveSheet.Cells(计数器,1)
范围(单元格,单元格。结束(xlToRight))。边框(xlEdgeBottom)。重量=xlMedium
如果结束
计数器=计数器+1
下一个
3:单元格。选择
Selection.RowHeight=12.75
Cells.EntireColumn.AutoFit
范围(“A1”)。选择
ActiveWorkbook.Sheets(“全部”)。激活
如果结束
下一个
2:
ActiveWorkbook.Sheets(“全部”)。激活
单元格。选择
自动筛选
范围(“A1”)。选择
'此子项将向每个工作簿添加工作表计数,它将从中复制粘贴
“顾问分布的数据透视表
暗淡如长
长
将行设置为整数
Dim行\u总计为整数
作为字符串的Dim str
n=3
'启动计数表
Windows(“顾问计数(1和2).xls”)。激活
图纸(“图纸3”)。选择
'选择部门列
单元格(3,1)。选择
rngend=lastrow()-1
当nActiveSheet.Name = "ALL"
Worksheets("ALL").Activate
Sheets("ALL").Select
         ' need to change to appropriate files

         Windows(new_wb).Activate
          Dim A2 As Integer
         A2 = 20
         For A2 = 0 To A2 Step 1
         If SheetExists("Sheet:" & A2) Then
         Sheets("Sheet:" & A2).Select
         Exit For
         End If
         Next
Private Function AddSheetToWorkbook(ByVal targetBook As Workbook, ByVal sheetName As String, Optional sheetIndexToUse As Long = 0) As Worksheet
    ' Either adds a new worksheet or uses existing sheet if sheetIndexToUse was provided.

    Dim targetSheet As Worksheet
    If sheetIndexToUse < 1 Then
        Set targetSheet = targetBook.Worksheets.Add
    Else
        Set targetSheet = targetBook.Worksheets(sheetIndexToUse) ' Will raise error if sheetIndex > Worksheets.Count
    End If
    targetSheet.Name = sheetName

    Set AddSheetToWorkbook = targetSheet
End Function

Private Function CreateAllSheet(ByVal targetBook As Workbook) As Worksheet
    Set CreateAllSheet = AddSheetToWorkbook(targetBook, sheetName:="ALL", sheetIndexToUse:=1)
End Function

Private Function CreateAdviserSheet(ByVal targetBook As Workbook, ByVal Adviser As String) As Worksheet
    Set CreateAdviserSheet = AddSheetToWorkbook(targetBook, sheetName:=Adviser)
End Function

Private Function CreateCountSheet(ByVal targetBook As Workbook) As Worksheet
    Set CreateCountSheet = AddSheetToWorkbook(targetBook, sheetName:="Count")
End Function

Private Function GetLastRow(ByVal targetSheet As Worksheet, Optional ByVal columnToUse As Variant = "A") As Long
    GetLastRow = targetSheet.Cells(targetSheet.Rows.Count, columnToUse).End(xlUp).Row
End Function

Private Function GetLastColumn(ByVal targetSheet As Worksheet, Optional ByVal rowToUse As Long = 1) As Long
    GetLastColumn = targetSheet.Cells(rowToUse, targetSheet.Columns.Count).End(xlToRight).Column
End Function

Private Function GetLastCell(ByVal targetSheet As Worksheet) As Range
    Dim lastRow As Long
    lastRow = GetLastRow(targetSheet)

    Dim lastColumn As Long
    lastColumn = GetLastColumn(targetSheet)

    Set GetLastCell = targetSheet.Cells(lastRow, lastColumn)
End Function

Private Function GetRowsMatchingCriteria(ByVal targetSheet As Worksheet, ByVal targetField As Long, ByVal Criterion As String)
    Dim includingHeaders As Range
    Set includingHeaders = targetSheet.Range("A1", GetLastCell(targetSheet))

    With includingHeaders
        .AutoFilter
        .AutoFilter Field:=targetField, Criteria1:=Criterion

        On Error Resume Next
        Set GetRowsMatchingCriteria = .SpecialCells(xlCellTypeVisible)
        On Error GoTo 0

        .AutoFilter
    End With
End Function

Private Function GetRowsMatchingDept(ByVal targetSheet As Worksheet, ByVal Dept As String) As Range
    Set GetRowsMatchingDept = GetRowsMatchingCriteria(targetSheet, targetField:=60, Criterion:=Dept)
End Function

Private Function GetRowsMatchingAdviser(ByVal targetSheet As Worksheet, ByVal Adviser As String) As Range
    Set GetRowsMatchingAdviser = GetRowsMatchingCriteria(targetSheet, targetField:=61, Criterion:=Adviser)
End Function

Private Sub AdjustRowAndColumnWidths(ByVal targetSheet As Worksheet)
    With targetSheet.Range("A1", GetLastCell(targetSheet))
        .RowHeight = 12.75
        .EntireColumn.AutoFit
    End With
End Sub

Private Sub SortSheetContents(ByVal targetSheet As Worksheet)
    'sort records by dept, then by adv_name, then by id
    With targetSheet
        .Range("A2").Sort Key1:=.Range("BH1"), _
            Key2:=.Range("BI1"), Key3:=.Range("C1"), _
            Header:=xlYes
    End With
End Sub

Private Sub CopyDataToSheetAndFormat(ByVal rangeToCopy As Range, ByVal topLeftPasteCell As Range)
    ' Copies data to a sheet, formats and sorts.
    Dim destinationSheet As Worksheet
    Set destinationSheet = topLeftPasteCell.Parent

    rangeToCopy.Copy Destination:=topLeftPasteCell
    AdjustRowAndColumnWidths targetSheet:=destinationSheet
    SortSheetContents targetSheet:=destinationSheet
End Sub

Private Sub AddBordersToAdviserSheet(ByVal adviserSheet As Worksheet)
    'place the neccessary borders (seperators)
    '31 is the number of the Major_code column
    Const MAJOR_CODE_COLUMN_INDEX  As Long = 31

    Dim lastRow As Long
    lastRow = GetLastRow(adviserSheet, MAJOR_CODE_COLUMN_INDEX)

    With adviserSheet
        Dim targetRange As Range
        Set targetRange = .Range(.Cells(2, MAJOR_CODE_COLUMN_INDEX), .Cells(lastRow, MAJOR_CODE_COLUMN_INDEX))
    End With
    Debug.Assert targetRange.Columns.Count = 1

    Dim cell As Range
    For Each cell In targetRange
        If cell.Value <> cell.Offset(1).Value Then
            ' Might be better to work from sheet's last column to left
            ' or working out last column before entering loop.
            adviserSheet.Range(cell, cell.End(xlToRight)).Borders(xlEdgeBottom).Weight = xlMedium
        End If
    Next cell
End Sub

Private Function GetDataWorksheet() As Worksheet
    Dim folderPath As String
    folderPath = ThisWorkbook.Path & "\"

    Dim dataWorkbook As Workbook
    Set dataWorkbook = Workbooks.Open(folderPath & "data_file.xls", ReadOnly:=True)

    ' Not sure if it is the only sheet in the workbook or not.
    ' If possible, refer to sheet by sheet name.
    Set GetDataWorksheet = dataWorkbook.Worksheets(1)
End Function

Private Function GetAdviserCountsWorksheet() As Worksheet
    Dim targetBook As Workbook
    ' This will raise an error (if book is not already open) so maybe
    ' provide a full path instead.
    Set targetBook = Application.Workbooks("adviser counts (1 & 2).xls")
    Set GetAdviserCountsWorksheet = targetBook.Worksheets("Sheet3")
End Function

Private Function GetAdviserRangeInPivotTable(ByVal adviserCountsSheet As Worksheet, ByVal Dept As String)
    ' There are probably better ways of doing this (e.g. interacting with the
    ' PivotTable's properties/methods -- rather than just iterating over a range)

    Dim lastRow As Long
    lastRow = GetLastRow(adviserCountSheet)

    With adviserCountsSheet
        Dim targetRange As Range
        Set targetRange = .Range("A3", .Cells(lastRow, "A"))

        Dim startRowIndex As Variant
        startRowIndex = Application.Match(Dept, targetRange, 0)

        Dim endRowIndex As Variant
        endRowIndex = Application.Match(Dept & " Total", targetRange, 0)

        Debug.Assert IsNumeric(startRowIndex)
        Debug.Assert IsNumeric(endRowIndex)
        Debug.Assert endRowIndex > startRowIndex

        Set GetAdviserRangeInPivotTable = .Rows(startRowIndex & ":" & endRowIndex)
    End With
End Function

Private Sub ReorderSheets(ByVal targetWorkbook As Workbook)
    ' Moves "ALL" to first, "Count" to second. Does not check if
    ' sheets exist. Will raise an error (if they do not).
    Dim allSheet As Worksheet
    Set allSheet = targetWorkbook.Worksheets("ALL")

    Dim countSheet As Worksheet
    Set countSheet = targetWorkbook.Worksheets("Count")

    allSheet.Move Before:=targetWorkbook.Worksheets(1)
    countSheet.Move After:=allSheet
End Sub

Private Sub FinaliseAndSaveWorkbook(ByVal targetWorkbook As Workbook, ByVal Dept As String)
    ReorderSheets targetWorkbook

    Dim outputFilePath As String
    outputFilePath = ThisWorkbook.Path & "\" & Dept

    ' Currently code does not check if parent folder exists
    ' and whether filename only contains legal characters.

    targetWorkbook.SaveAs Filename:=outputFilePath ' Do you want to specify a file format here too?

End Sub

Sub Macro1()

    Dim dataSheet As Worksheet
    Set dataSheet = GetDataWorksheet()

    Dim adviserCountsSheet As Worksheet
    Set adviserCountsSheet = GetAdviserCountsWorksheet()

    Dim created As Integer
    created = 1

    Dim Dept As Range
    For Each Dept In dataSheet.Columns(1).Cells
        If (Dept.Text = "") Then Exit For

        ' Might be possible to restructure such that you no longer
        ' need the "created" variable.
        If (created = 1) Then
            Dim newWorkbook As Workbook ' Needs a better name
            Set newWorkbook = Application.Workbooks.Add
        End If

        Dim cellsToCopy As Range
        Set cellsToCopy = GetRowsMatchingDept(ThisWorkbook.Worksheets("Sheet1"), Dept.Text)
        Debug.Assert Not (cellsToCopy Is Nothing)

        created = 0

        If cellsToCopy.Columns(1).Cells.CountLarge < 4000 Then
            Dim allSheet As Worksheet
            Set allSheet = CreateAllSheet(newWorkbook)

            CopyDataToSheetAndFormat cellsToCopy, allSheet.Range("A1")

            Dim Adviser As Range
            For Each Adviser In dataSheet.Columns(2).Cells
                If (Adviser.Text = "") Then Exit For

                Set cellsToCopy = GetRowsMatchingAdviser(ThisWorkbook.Worksheets("Sheet1"), Adviser.Text)

                If cellsToCopy.Columns(1).Cells.CountLarge < 1500 Then
                    Dim adviserSheet As Worksheet
                    Set adviserSheet = CreateAdviserSheet(newWorkbook, Adviser.Text)

                    CopyDataToSheetAndFormat cellsToCopy, adviserSheet.Range("A1")
                    AddBordersToAdviserSheet adviserSheet

                    Set adviserSheet = Nothing
                End If
            Next Adviser

            ' This sub will add the sheet Count to each workbook it will simply copy paste from
            ' the pivot table of the adviser distribution

            Dim countSheet As Worksheet
            Set countSheet = CreateCountSheet(newWorkbook)

            adviserCountsSheet.Rows("1:2").Copy countSheet.Range("A1")

            Set cellsToCopy = GetAdviserRangeInPivotTable(adviserCountsSheet, Dept:=Dept.Text)
            cellsToCopy.Copy countSheet.Range("A3")

            FinaliseAndSaveWorkbook newWorkbook, Dept:=Dept.Text
            newWorkbook.Close

            created = 1
        End If

    Next Dept

    dataSheet.Parent.Close
End Sub