vba - 运行循环以根据标题名称检查列,并在缺少列时插入列

标签 vba excel csv

我是 VBA 新手,我的任务是创建一个宏来清理和保存 .csv 文件。到目前为止,我已经能够将来自 Stack Overflow 上其他已回答问题的脚本放在一起,但最后一部分让我望而却步。

到目前为止,我可以打开,检查需要删除的列,删除它们,然后另存为新文件。我需要做的是检查列是否丢失并插入它们,以便 csv 文件始终具有相同的标题行。

例如:

假设所有必要的列的第一行单元格值为“Alpha”、“Bravo”、“Charlie”、“Delta”、“Echo”、“Foxtrot”、“Golf”

但有时我们收到的 CSV 文件仅从“Alpha”变为“Echo”

我需要检查这一点,然后按各自的顺序插入“foxtrot”和“Golf”列。我该怎么做呢?

似乎通过一些小的调整和更多的代码,我可以修改我的列删除脚本(我找到了 here)来做到这一点。

Dim rngFound As Range
      Dim rngDel As Range
      Dim arrColumnNames() As Variant
      Dim varName As Variant
      Dim strFirst As String

      arrColumnNames = Array("Hotel","India","Julliet")

      For Each varName In arrColumnNames
          Set rngFound = Rows(1).Find(varName, Cells(1, Columns.Count), xlValues, xlPart)
          If Not rngFound Is Nothing Then
              strFirst = rngFound.Address
              Do
                  If rngDel Is Nothing Then Set rngDel = rngFound Else Set rngDel = Union(rngDel, rngFound)
                  Set rngFound = Rows(1).Find(varName, rngFound, xlValues, xlPart)
              Loop While rngFound.Address <> strFirst
          End If
      Next varName

      If Not rngDel Is Nothing Then rngDel.EntireColumn.Delete

      Set rngFound = Nothing
      Set rngDel = Nothing
      Erase arrColumnNames

但这有点超出我的想象,因为我从未使用过 VBA。有人可以提供一些方向吗?

最佳答案

最简单的方法是将所有缺失的列放在右侧,然后从左到右排序(而不是典型的从上到下)。但是,我假设您的列标题标签不像您提供的漂亮的字母标签,因此这意味着自定义排序,您必须为此提供所有列名称。

Array Filter方法可以快速确定您是否有不属于的列,但是它是模式匹配而不是完全匹配,因此可能会出现误报。您自己的结果将取决于您使用的列标题标签的实际名称。如果这是一个不合适的方法,那么只需遍历每个。

Sub fixImportColumns()
    Dim c As Long, vCOLs As Variant

    vCOLs = Array("Alpha", "Bravo", "Charlie", "Delta", "Echo", _
                  "Foxtrot", "Golf", "Hotel", "India", "Julliet")

    With Worksheets("myImportedCSV")

        'add non-existent columns from list
        For c = LBound(vCOLs) To UBound(vCOLs)
            If IsError(Application.Match(vCOLs(c), .Rows(1), 0)) Then _
                .Cells(1, Columns.Count).End(xlToLeft).Offset(0, 1) = vCOLs(c)
        Next c

        With .Cells(1, 1).CurrentRegion

            'get rid of columns not in list (from right-to-left)
            For c = .Columns.Count To 1 Step -1
                If UBound(Filter(vCOLs, .Cells(1, c), True, vbTextCompare)) < 0 Then _
                    .Columns(c).EntireColumn.Delete
            Next c

            'create a custom list for the sort order
            Application.AddCustomList ListArray:=vCOLs

            'clear any remembered sort
            .Parent.Sort.SortFields.Clear

            'sort the columns into the correct order
            .Cells.Sort Key1:=.Rows(1), Order1:=xlAscending, _
                        Orientation:=xlLeftToRight, Header:=xlNo, MatchCase:=False, _
                        OrderCustom:=Application.CustomListCount + 1
        End With
    End With

End Sub

Range.Sort method 虽然没有被广泛使用,可以从左到右对数据 block 进行排序,并使用自定义列表作为排序顺序。

关于vba - 运行循环以根据标题名称检查列,并在缺少列时插入列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35326910/

相关文章:

python - 将表拆分为小型 Python

ruby-on-rails - Rails 4 CSV 导入并将值设置为键值

excel - 如何浏览保存目录?

vba - SpecialCells(xlCellTypeBlanks).EntireRow.Delete 未找到任何单元格

arrays - 使用Excel VBA在多维数组中查找(而不是删除)重复值(行)

java - 在Android中更新CSV文件后更新Listview

excel - 如何将变量分配给数据验证公式 1 := in Excel VBA?

excel - 如何确保列中所有格式化为文本的 Excel 单元格实际上都是

excel - 将字符串附加到 VBA 中的粗体字符串

c# - 将 Excel 互操作的 Range.Value2 转换为字符串