arrays - 扩展每个列单元格的列单元格

标签 arrays vba excel loops

我有 3 组不同的数据(在不同的列中)

  1. A 列中的动物(5 种不同种类)
  2. B 列中的水果(1000 种不同)
  3. C 列中的国家/地区(10 种不同类型)

通过这 3 个数据集合,我希望收到 5×1000×10 列中总共 50k 个相应元素。 E F G(每种动物对应每种水果和每个国家)。

这可以通过手动复制和粘贴值来完成,但这需要很长时间。有没有办法通过 VBA 代码自动化它或

是否有像上面介绍的那样适用于无限数据集的通用公式?如果有不清楚的地方,请告诉我。

下面是一个较小的数据示例以及结果:

         Expanding data sets for each in other

最佳答案

我通过通用收集,您希望它能够容纳任意数量的列以及每列中任意数量的条目。一些变体数组应提供计算每个值的重复周期所需的维度。

Option Explicit

Sub main()
    Call for_each_in_others(rDATA:=Worksheets("Sheet3").Range("A3"), bHDR:=True)
End Sub

Sub for_each_in_others(rDATA As Range, Optional bHDR As Boolean = False)
    Dim v As Long, w As Long
    Dim iINCROWS As Long, iMAXROWS As Long, sErrorRng As String
    Dim vVALs As Variant, vTMPs As Variant, vCOLs As Variant

    On Error GoTo bm_Safe_Exit
    appTGGL bTGGL:=False

    With rDATA.Parent
        With rDATA(1).CurrentRegion
            'Debug.Print rDATA(1).Row - .Cells(1).Row
            With .Resize(.Rows.Count - (rDATA(1).Row - .Cells(1).Row), .Columns.Count).Offset(2, 0)
                sErrorRng = .Address(0, 0)
                vTMPs = .Value2
                ReDim vCOLs(LBound(vTMPs, 2) To UBound(vTMPs, 2))
                iMAXROWS = 1
                'On Error GoTo bm_Output_Exceeded
                For w = LBound(vTMPs, 2) To UBound(vTMPs, 2)
                    vCOLs(w) = Application.CountA(.Columns(w))
                    iMAXROWS = iMAXROWS * vCOLs(w)
                Next w

                'control excessive or no rows of output
                If iMAXROWS > Rows.Count Then
                    GoTo bm_Output_Exceeded
                ElseIf .Columns.Count = 1 Or iMAXROWS = 0 Then
                    GoTo bm_Nothing_To_Do
                End If

                On Error GoTo bm_Safe_Exit
                ReDim vVALs(LBound(vTMPs, 1) To iMAXROWS, LBound(vTMPs, 2) To UBound(vTMPs, 2))
                iINCROWS = 1
                For w = LBound(vVALs, 2) To UBound(vVALs, 2)
                    iINCROWS = iINCROWS * vCOLs(w)
                    For v = LBound(vVALs, 1) To UBound(vVALs, 1)
                        vVALs(v, w) = vTMPs((Int(iINCROWS * ((v - 1) / UBound(vVALs, 1))) Mod vCOLs(w)) + 1, w)
                    Next v
                Next w
            End With
        End With
        .Cells(2, UBound(vVALs, 2) + 2).Resize(1, UBound(vVALs, 2) + 2).EntireColumn.Delete
        If bHDR Then
            rDATA.Cells(1, 1).Offset(-1, 0).Resize(1, UBound(vVALs, 2)).Copy _
                Destination:=rDATA.Cells(1, UBound(vVALs, 2) + 2).Offset(-1, 0)
        End If
        rDATA.Cells(1, UBound(vVALs, 2) + 2).Resize(UBound(vVALs, 1), UBound(vVALs, 2)) = vVALs
    End With

    GoTo bm_Safe_Exit
bm_Nothing_To_Do:
    MsgBox "There is not enough data in  " & sErrorRng & " to perform expansion." & Chr(10) & _
           "This could be due to a single column of values or one or more blank column(s) of values." & _
            Chr(10) & Chr(10) & "There is nothing to expand.", vbInformation, _
           "Single or No Column of Raw Data"
    GoTo bm_Safe_Exit
bm_Output_Exceeded:
    MsgBox "The number of expanded values created from " & sErrorRng & _
           " (" & Format(iMAXROWS, "\> #, ##0") & " rows × " & UBound(vTMPs, 2) & _
           " columns) exceeds the rows available (" & Format(Rows.Count, "#, ##0") & ") on this worksheet.", vbCritical, _
           "Too Many Entries"
bm_Safe_Exit:
    appTGGL
End Sub

Sub appTGGL(Optional bTGGL As Boolean = True)
    Application.EnableEvents = bTGGL
    Application.ScreenUpdating = bTGGL
End Sub

将列标题标签放在从 A 列开始的第 2 行中,并将数据直接放在其下方。

我添加了一些错误控制来警告工作表上的行数超出。这通常不会被考虑,但将不确定数量的列中的值的数量相互相乘可以快速产生大量结果。超过 1,048,576 行并非不可预见。

         Variant Array expansion

关于arrays - 扩展每个列单元格的列单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31472816/

相关文章:

Javascript多维数组返回第一个值,然后失败

arrays - 为什么 Perl 中的连接打印数组的 COUNT 而不是数组本身

vba - 如何在整个工作表中查找包含字符串的单元格

excel - 在没有数据透视表的情况下根据每日数据计算月平均值

vba - 保护允许通过 VBA 代码插入图像的 excel 工作表

javascript读取csv文件返回空数组

c++ - 数组打印奇怪的字符,例如∟@

ms-access - 如何高效地进行Access VBA + SQL开发?

Excel宏-动态设置打印区域

excel - Excel 中分类数据的单热(虚拟)编码