【问题标题】:EXCEL VBA: My macro is creating a 3D dimension arrayEXCEL VBA:我的宏正在创建一个 3D 维度数组
【发布时间】:2021-01-06 20:28:47
【问题描述】:

我有很多招聘数据,我想使用数组重新排列、分离和修改。数据包括每个候选人的第一阶段、第二阶段和第三阶段面试的所有信息。这个想法是将每个阶段分开到自己的工作表上(例如面试 1、面试 2、面试 3)。然后还要创建一个表格,其中包含每个候选人的所有三个阶段的信息。

首先,我通过将范围 ("A1:AV10000") 声明为变量来创建所有数据的数组。

然后我创建了一个循环来遍历这些数据,并使用循环中的 IF 函数将发生的每种类型的事件分离到它们自己的数组中。如果满足条件,则创建一个新数组并将满足条件的每一行添加到数组中。

但是,我相信我的数组正在制作成 3D 数组,并且我确定如何编辑代码以使其保持 2Darray。我理解为什么代码可能会创建 3D 数组(由于在循环中迭代 1),但是我不确定如何编写代码,以便它包含该行的所有数据并且只迭代如下所示。

例如目前它是 (1)(1,1),(1)(1,2) 然后是 (2)(1,1),(2)(1,2) 然后是 (3)(1,1),(3 )(1,2)。 我认为如果它是(1,1)(1,2)然后是(2,1)(2,2)然后是(3,1)(3,2),它会起作用。 Screenshot of array format from local window

Sub AddProcessStageToArray(SourceWorksheet, RawDataArray, LastrowData, WhatStage, ArrayOutput)

For i = LBound(RawDataArray) To UBound(RawDataArray)
    If RawDataArray(i, 13) = WhatStage And RawDataArray(i, 38) <> "NOK" Then
        o = o + 1

        'Dim ArrayName() As Variant
        ReDim Preserve ArrayOutput(o)
        ArrayOutput(o) = Application.Index(SourceWorksheet.Range("A1:AO" & LastrowData), i, 0)
        
    End If
Next

End Sub


正在调用代码,如下所示。

Sub AddITWToArray()

Dim DataWs As Worksheet: Set DataWs = ThisWorkbook.Sheets("DATA")
Dim PoolOfWeekWs As Worksheet: Set PoolOfWeekWs = ThisWorkbook.Sheets("Pool of the week")

Dim LastrowData As Long: LastrowData = DataWs.Range("A" & Rows.Count).End(xlUp).Row
Dim LastColData As Long: LastColData = DataWs.Cells(1 & DataWs.Columns.Count).End(xlToLeft).Column

Dim LastColDataString As String: LastColDataString = Split(Cells(1, LastColData).Address, "$")(1)

Dim DataRange As Range: Set DataRange = DataWs.Range("A1:" & LastColDataString & LastrowData)
Dim DataArr As Variant: DataArr = DataWs.Range("A1:AO" & LastrowData)

'Loop through Data array, if interview process = PQL, add to table. If interview proces = 1sTITW find postion and add data, if 2ndITW find postion and highlight, if 3rd find postion and highlight

Dim PoolofWeekTableLRow As Long: PoolofWeekTableLRow = PoolOfWeekWs.Range("A" & Rows.Count).End(xlUp).Row
'PoolOfWeekWs.Rows("3:" & PoolofWeekTableLRow).ClearContents

Dim i, o As Long
Dim RowNumberArr As Variant


'Create PQLArray
Dim PQLArray() As Variant
Call AddProcessStageToArray(DataWs, DataArr, LastrowData, "Prequalification", PQLArray)


'Create 1ITWArray
Dim FirstITWArray() As Variant
Call AddProcessStageToArray(DataWs, DataArr, LastrowData, "Candidate Interview 1", FirstITWArray)

'Create 2ITWArray
Dim SecondITWArray() As Variant
Call AddProcessStageToArray(DataWs, DataArr, LastrowData, "Candidate Interview 2+", SecondITWArray)

'Create PPLArray
Dim PPLArray() As Variant
Call AddProcessStageToArray(DataWs, DataArr, LastrowData, "Candidate Interview 2*", PPLArray)

【问题讨论】:

  • 得到的数组不是3D数组,是数组的数组。一个如此命名的锯齿状阵列。为了返回这样一个数组,我认为将Sub 转换为Function 会很好。而且(即使在现有的Sub 中)最好正确声明所有Sub/Function 参数(SourceWorksheet As Worksheet, RawDataArray, LastrowData As Long, WhatStage As String)。但你真正的问题在哪里?您想读取/使用/返回锯齿状数组元素吗?
  • 是的。 Application.Index(SourceWorksheet.Range("A1:AO" &amp; LastrowData), i, 0) 返回一个二维数组,因此您正在创建一个数组数组。在这种情况下,我通常使用字典来收集和组织数据,然后在遍历所有数据后将其输出为二维数组。 Redim Preserve 在应用于多维数组时既有开销又有限制。
  • @FaneDuru 我明白了。谢谢你指出我不知道。我想要做的是将数组元素返回到每个元素的特定工作表中。然后使用创建的所有数组的组合,用来自所有阶段的数据组合信息填充表格。我正在努力将数据从数组传递到特定的工作表
  • @RonRosenfeld 我现在明白了,有没有办法在不创建数组的锯齿状/数组的情况下将一整行元素添加到数组中?字典是唯一的方法吗?
  • 您可以编写每个单独的元素。但是使用字典要简单得多。

标签: arrays excel vba for-loop


【解决方案1】:

请尝试下一个改编的功能:

Function AddProcessStageToArray(SourceWorksheet As Worksheet, RawDataArray, LastrowData As Long, WhatStage As String) As Variant
Dim ArrayOutput() As Variant, o As Long, i As Long, j As Long

ReDim ArrayOutput(1 To UBound(RawDataArray, 2), 1 To UBound(RawDataArray, 2))
For i = LBound(RawDataArray) To UBound(RawDataArray)
    If RawDataArray(i, 13) = WhatStage And RawDataArray(i, 38) <> "NOK" Then
        o = o + 1
        For j = 1 To UBound(RawDataArray, 2)
            ArrayOutput(j, o) = RawDataArray(i, j)
        Next j
    End If
Next
ReDim Preserve ArrayOutput(1 To UBound(RawDataArray, 2), 1 To o)
AddProcessStageToArray = WorksheetFunction.Transpose(ArrayOutput)
End Function

可以这样调用:

Sub testAddProcessStToArr()
  Dim DataWs As Worksheet, DataArr As Variant, LastrowData As Long
  
  Set DataWs = ThisWorkbook.Sheets("DATA")
    LastrowData = DataWs.Range("A" & rows.count).End(xlUp).row
    DataArr = DataWs.Range("A1:AO" & LastrowData)
    Dim PQLArray() As Variant
    PQLArray = AddProcessStageToArray(DataWs, DataArr, LastrowData, "Prequalification")
    Dim NewSheet as Worksheet
    Set NewSheet = ActiveWorkbook.Sheets.Add
    NewSheet.Range("A1").Resize(UBound(PQLArray), UBound(PQLArray, 2)).Value = PQLArray
End Sub

已编辑

请也尝试下一种方法,包括根据条件标准对行进行初步计数,然后使用它们来填充最终数组。要使用的适配函数将是下一个:

Function AddProcessStageToArr(RawDataArray, arrNo As Variant) As Variant
 Dim ArrayOutput() As Variant, o As Long, i As Long, j As Long

 ReDim ArrayOutput(1 To UBound(arrNo) + 1, 1 To UBound(RawDataArray, 2))
 For i = 0 To UBound(arrNo)
    o = o + 1
    For j = 1 To UBound(RawDataArray, 2)
        ArrayOutput(o, j) = RawDataArray(arrNo(i), j)
    Next j
 Next
 AddProcessStageToArr = ArrayOutput
End Function

上面的函数应该按下面的方式调用:

Sub testAddProcessStToArrBis()
  Dim DataWs As Worksheet, DataArr As Variant, LastrowData As Long
  Dim arrNo As Variant, i As Long, k As Long
  
  Set DataWs = ActiveSheet
    LastrowData = DataWs.Range("A" & rows.count).End(xlUp).row
    DataArr = DataWs.Range("A1:AO" & LastrowData).Value
    ReDim arrNo(UBound(DataArr))
    For i = 1 To UBound(DataArr)
        If DataArr(i, 13) = "Prequalification" And DataArr(i, 38) <> "NOK" Then
            arrNo(k) = i: k = k + 1
        End If
    Next i
    ReDim Preserve arrNo(k - 1)
    Dim PQLArray() As Variant
    PQLArray = AddProcessStageToArr(DataArr, arrNo)
    Dim NewSheet As Worksheet
    Set NewSheet = ActiveWorkbook.Sheets.Add(After:=DataWs)
    NewSheet.Range("A1").Resize(UBound(PQLArray), UBound(PQLArray, 2)).Value = PQLArray
End Sub

必须使用相同的功能,但将“资格预审”更改为“候选人面试 x”并为每个案例重新构建 arrNo...

【讨论】:

  • 谢谢@FaneDuru,我刚刚测试过了!似乎一切正常,但是我在最后一行得到一个应用程序定义的错误 1004。我希望以相反的方式管理阵列,因此 x 轴为 41,因此我切换了阵列的 o 和 j 计数器等。现在,一些数组被输出到工作表上,但在 4000 行中的第 450 行停止。
  • @0Marine0:你说的是哪条“最后一行”?测试SubFunction 行?然后,您无法在函数中切换具有行的列! Resize Preserve 起作用的维度是只有最后一个。无论如何,在仅保留保留数据的数组元素 (o) 之后,就行和列而言,数组被转置。你能更好地解释一下你尝试了什么以及你需要什么吗?
  • 转置出错了,所以我把转置拿出来,然后正常输入到数组中。我试图解决的问题是我有数千行数据,来自招聘过程的各个阶段。现在我需要提取每个面试阶段的数据并将其放入表格中。但是,候选人的名字可能会出现多次(1st stage、2ndstage、3rdstage)。数据将在决赛表中组织,为每个候选人显示一个条目,显示所有三个阶段的数据。这是最终结果,但是我试图创建单独的数组来开始。
  • 这个阶段只是询问数组,但你认为我应该重写这个问题来描述整个结果吗?我认为字典可能是思考它的最佳方式。
  • @0Marine0 好吧,Application.Transpose 有一些限制(65535 个数组元素和任何元素最多 255 个字符)......我无法理解“大量招聘数据”可能超过前面提到的限制。如果在构建数组时完成的转置没有问题,则未显示其所有元素的问题来自代码调整范围以接收所有数组元素的方式。您必须使用最后一个子代码行:NewSheet.Range("A1").Resize(UBound(PQLArray, 2), UBound(PQLArray)).Value = PQLArray。我的意思是,行必须与列交换。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-04
  • 1970-01-01
  • 1970-01-01
  • 2013-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多