Excel vba基于组合框中的多个值从单元格中获取值

Excel vba基于组合框中的多个值从单元格中获取值,vba,excel,Vba,Excel,我有一个excel文档,我想根据组合框中的多个值从单元格中提取值。 第一个组合框包含列“Teknik”中的所有值。 第二个组合框包含列“Kund”中的所有值。 第三个组合框包含“年”行、2016年、2017年的所有值… 第四个组合框包含一月到十二月的所有月份 如果我选择 VoLTE->Kund1->2016->1月 我想我应该首先找到客户,年份和月份,然后遍历单元格,但在vba中我不知道如何将所有变量联系在一起,以便在选择上述变量时获得正确的值。 这有助于我将值连接到一个值。我没有尝试创建任何


我有一个excel文档,我想根据组合框中的多个值从单元格中提取值。

第一个组合框包含列“Teknik”中的所有值。
第二个组合框包含列“Kund”中的所有值。
第三个组合框包含“年”行、2016年、2017年的所有值…
第四个组合框包含一月到十二月的所有月份

如果我选择
VoLTE->Kund1->2016->1月

我想我应该首先找到客户,年份和月份,然后遍历单元格,但在vba中我不知道如何将所有变量联系在一起,以便在选择上述变量时获得正确的值。


这有助于我将值连接到一个值。

我没有尝试创建任何满足您要求的代码,因此下面介绍如何开发该代码

我不清楚整理工作表是否有帮助。我会从你拥有的东西开始,但如果我以后认为有帮助的话,我保留整理的权利

如果您不熟悉VBA,则可能不熟悉
ReDim
。这个语句在VB.Net中可用,但我知道没有其他语言包含它,所以我假设它在C#中不可用

上面定义了元素为1到5的固定大小字符串数组。VBA允许您指定数组的下限。我想C#没有

Dim X() As String
上面指定了一个动态字符串数组,我将在运行时调整该字符串的大小,或者调整其大小

Dim X() As String
ReDim X(1 To 5)
ReDim X(1 To 10)
ReDim Preserve X(1 To 10)
  • Dim X()作为字符串
    定义X
  • ReDim X(1到5)
    调整X的大小以容纳元素1到5
  • ReDim X(1到10)
    释放用于垃圾收集的原始X,并创建一个新的X来保存元素1到10
  • ReDim Preserve X(1到10)
    创建一个新的X来保存元素1到10,从原始X复制值,然后释放原始X进行垃圾收集
当有人事先不知道X需要有多大时,有时会在循环中看到
ReDim Preserve X(1到UBound(X)+1)
。您可以想象这是非常方便的,但是如果有足够大的循环,它会变得非常慢,通常不推荐使用

我假设您没有大量的唯一值,因此减速不会太重要,因此我将从
ReDim Preserve X(1到UBound(X)+1)
开始,但如果这会导致问题,请准备尝试不同的方法

你说你有组合框。如果用户不喜欢其中一个,组合框允许用户输入自己的值。这在你的场景中毫无意义。您需要的列表框实际上与组合框相同,而用户没有输入值的选项

我将使用范围、范围的并集和范围的交集来控制所需单元格的选择。考虑这个演示宏:

Sub Demo()

  Const CellsPerSelection As Long = 2

  Dim RngColA As Range
  Dim RngColB As Range
  Dim RngYYMM As Range
  Dim RngSelected As Range
  Dim Cell As Range
  Dim Count As Long

  Set RngColA = Rows("5:49")
  Set RngColB = Union(Rows(8), Rows(40), Rows(55), Rows(80))
  Set RngYYMM = Union(Columns(5), Columns(6))

  Set RngSelected = Intersect(RngColA, RngColB, RngYYMM)

  If RngSelected Is Nothing Then
    Debug.Print "No intersect"
  Else
    Count = 0
    For Each Rng5 In RngSelected
      If Count = 0 Then
        Debug.Print "Pair:";
      End If
      Debug.Print " " & Rng5.Address;
      Count = Count + 1
      If Count = CellsPerSelection Then
        Debug.Print
        Count = 0
      End If
    Next
  End If

End Sub
我不想解释VBA。如果你不理解一个特定的语句,你应该能够很容易地找到它。不过,如果有必要,请带着问题回来。我想解释的是该代码的目标

考虑:
设置RngColA=Rows(“5:49”)
。在真实的宏中,我会有如下列表:

VoLTE     Rows("5:49")
XYZ       Rows("50:75")
UVW       Rows("76:100")
因此,宏可以将选择“VoLTE”转换为范围
行(“5:49”)
。这里我刚刚将RngColA设置为这个范围

考虑
Set RngColB=Union(第8行、第40行、第55行、第80行))
。在这里,我将列表想象为:

Kund1     Union(Rows(8), Rows(40), Rows(55), Rows(80))
Kund2     Union(Rows(9), Rows(35), Rows(65), Rows(95))
Kund3     Union(Rows(12), Rows(70), Rows(100), Rows(105))
“Kund1”对应的值是从B列中包含“Kund1”的所有行的并集创建的范围。注意,我允许值“Kund1”在“VoLTE”中出现两次。我不知道这是否可能。如果不可能,可以简化宏末尾的代码

Set rngymm=Union(第(5)列、第(6)列))
类似,但给出了2016年1月的列

Set RngSelected=Intersect(RngColA、RngColB、rngymm)
提取选定范围之间的重叠。这种重叠是
$E$8:$F$8,$E$40:$F$40
。如果“Kund1”只有一个值,则为
$E$8:$F$8

底部的代码允许没有重叠。如果存在重叠,它将
RngSelected
拆分为单元对。我只是将地址输出到即时窗口,但对于您来说,您将使用它向用户显示值

在使用此宏的等效项向用户显示值之前,需要创建三个列表,从中选择值

对于第一个列表,向下运行列A给出:

VoLTE     on row 5
XYZ       on row 50
UVW       on row 76
另外,您需要发现最后一行的值是第100行。这是创建列表所需的全部信息

我会把这个列表放在一个数组中。大多数语言都提供结构或结构。VBA称它们为用户类型,但这只是一个不同的名称。定义必须位于模块顶部:

Type ValueRange
  Value As String
  Rng As Range
End Type
数组定义可以是全局的,通常在子例程中:

Dim ColA() As ValueRange
Dim ColB() As ValueRange
Dim YYMM() As ValueRange

希望以上内容能有所帮助。

电子表格并不是真的想这样工作。您可以尝试设置一组命名范围,然后使用偏移量获取值,但这将是一场噩梦。例如,列范围2016和每个月之间没有关系。查找函数不会帮助您关联它们。在Excel中,我看到可行解决方案的唯一方法是重新构造工作表。您可以对第一个、月份和年份使用match,然后对种类列Step1进行循环,以处理Excel中的数据[或任何地方]:使所有输入数据尽可能统一。理想情况下,将所有内容与行和表一起使用,其中每一行都有一个唯一的ID
Type ValueRange
  Value As String
  Rng As Range
End Type
Dim ColA() As ValueRange
Dim ColB() As ValueRange
Dim YYMM() As ValueRange