excel 如何在代码中添加更多的文件名和头名

46scxncf  于 2023-08-08  发布在  其他
关注(0)|答案(2)|浏览(87)

我正在努力解决这个问题,但它超出了我的知识。
我想通过在代码中添加"Header Name"来提取更多列数据。但我的代码只适用于单头。
我试着添加一个像这样的数组
Const sHeader As String = Array("Category", "Names")等等。
但我得到一个错误。
我想Add File Names循环通过他们在文件夹和跳过其余的文件。
比如这个Const sFileName As String = Array("File1", "File2")等等。

我想通过标题分隔符复制并粘贴每个列。

如果有人能帮我这个忙,我将不胜感激。

Sub ImportColumns()
    
    ' Source
    Const sFilePattern As String = "*.xlsx"
    Const sExceptionsList As String = "Sheet1" ' comma-separated, no spaces
    Const sHeader As String = "Category"
    Const sHeaderRow As Long = 1
    ' Destination
    Const dColumn As String = "A"
    
    ' Source
    
    Dim sfd As FileDialog
    Set sfd = Application.FileDialog(msoFileDialogFolderPicker)
    'sfd.InitialFileName = "C:\Test\"
    
    Dim sFolderPath As String
    
    If sfd.Show Then
        sFolderPath = sfd.SelectedItems(1) & Application.PathSeparator
    Else
        'MsgBox "You canceled.", vbExclamation
        Beep
        Exit Sub
    End If
    
    Dim sFileName As String: sFileName = Dir(sFolderPath & sFilePattern)
    
    If Len(sFileName) = 0 Then
        'MsgBox "No files found.", vbExclamation
        Beep
        Exit Sub
    End If
    
    Dim sExceptions() As String: sExceptions = Split(sExceptionsList, ",")
    
    ' Destination
    
    Dim dwb As Workbook: Set dwb = ThisWorkbook ' workbook containing this code
    Dim dws As Worksheet: Set dws = dwb.ActiveSheet ' improve!
    Dim dfCell As Range
    Set dfCell = dws.Cells(dws.Rows.Count, dColumn).End(xlUp).Offset(1)
    
    ' Loop.
    
    Application.ScreenUpdating = False
    
    Dim swb As Workbook
    Dim sws As Worksheet
    Dim srg As Range
    Dim shrg As Range
    Dim sData() As Variant
    Dim sfCell As Range
    Dim slCell As Range
    Dim srCount As Long
    Dim wsCount As Long
    
    Do While Len(sFileName) > 0
        Set swb = Workbooks.Open(sFolderPath & sFileName)
        For Each sws In swb.Worksheets
            If IsError(Application.Match(sws.Name, sExceptions, 0)) Then
                Set shrg = sws.Rows(sHeaderRow)
                Set sfCell = shrg.Find(sHeader, shrg.Cells(shrg.Cells.Count), _
                        xlFormulas, xlWhole)
                If Not sfCell Is Nothing Then
                    Set sfCell = sfCell.Offset(1)
                    Set slCell = sfCell _
                        .Resize(sws.Rows.Count - sHeaderRow) _
                        .Find("*", , xlFormulas, , , xlPrevious)
                    If Not slCell Is Nothing Then
                        srCount = slCell.Row - sHeaderRow
                        Set srg = sfCell.Resize(srCount)
                    End If
                End If
                If srCount > 0 Then
                    If srCount = 1 Then
                        ReDim sData(1 To 1, 1 To 1): sData(1, 1) = srg.Value
                    Else
                        sData = srg.Value
                    End If
                    dfCell.Resize(srCount).Value = sData
                    Set dfCell = dfCell.Offset(srCount)
                    wsCount = wsCount + 1
                    srCount = 0
                End If
            End If
        Next sws
        swb.Close SaveChanges:=False
        sFileName = Dir
    Loop
                
    ' Save the destination workbook.
    'dwb.Save
                
    Application.ScreenUpdating = True
    
    MsgBox wsCount & " '" & sHeader & "' columns copied.", vbInformation
                
End Sub

字符串

gcuhipw9

gcuhipw91#

在我看来,“Do While”循环相当慢,我会尽量避免它们。相反,使用定义的“For”或“For each”循环。
关键是使用数组,并在每个“For”循环中询问存储在这些数组中的信息。
这里有一个想法(它还没有完成)使用“For”循环,一个在另一个里面。第一个是打开文件,第二个是打开工作表,第三个是检查标题。请检查变量“arrFiles(X)”和“arrHeaders(Y)”

Dim wbkSheet    As Worksheet
Dim Wbk         As Workbook
Dim X           As Double, Y As Double
Dim sHeaderRow  As Byte: sHeaderRow = 1
Dim shRg        As Range, sfCell As Range

'Here we set the values for the Files names and Table Headers names. They'll be Arrays
Dim arrFiles    As Variant: arrFiles = Array("File_1.xlsx", "Files_2.xlsx")
Dim arrHeader   As Variant: arrHeader = Array("Category", "Names")

'Loop to check every file that is in the Array
For X = LBound(arrFiles, 1) To UBound(arrFiles, 1)
  'Loop to open every file of the list
  'Example:
    Set Wbk = Workbooks.Open(sFolderPath & arrFiles(X))
  '...
    For Each wbkSheet In Wbk.Worksheets
    'Loop to open every sheet of the opened file.
        For Y = LBound(arrHeader, 1) To UBound(arrHeader, 1)
         'Loop to check every column of the sheet
         'Example:
            Set shRg = wbkSheet.Rows(sHeaderRow)
            Set sfCell = shRg.Find(arrHeader(Y), shRg.Cells(shRg.Cells.Count), xlFormulas, xlWhole)
         '...
        Next Y
        
    Next wbkSheet
Next X

字符串
使用此代码,您可以添加任意多的文件和头文件。
现在,在我看来,最好的解决方案将是使用ADO Excel,它是更快的方式(它使用SQL查询),你不需要打开文件。循环将更短,因为您只需建立SQL查询。

jxct1oxe

jxct1oxe2#

使用Const初始化数组的一个建议是这样声明头:

Const ALL_HEADERS As String = "Category,Names"

字符串
然后,当你设置数组时,它将是:

Dim sHeader() As String
sHeader = Split(ALL_HEADERS, ",")


你的数组已经设置。

相关问题