【问题标题】:referencing a range of cells in a different worksheet via indexing vba通过索引 vba 引用不同工作表中的一系列单元格
【发布时间】:2017-12-12 22:00:17
【问题描述】:

在 excel 中,我有(包含许多分类变量列的表):

A   E
S   E
D   YU
R   T
FD  R
FD  RT
D   YU
S   T
AS  R
D   RR
D   R

我想要(每个单独词的频率):

A   1   E   2
S   2   YU  2
D   4   T   2
R   1   R   3
FD  2   RT  1
AS  1   RR  1

我正在计算每个术语的频率。我可以手动单独计算:

Sub ff()
    Range("B1:B6").Select
    Selection.FormulaArray = "=COUNTIFS(Sheet1!C[-1],Sheet2!RC[-1]:R[5]C[-1])"
    Range("D1").Select

End Sub

但我想遍历每一列并将频率计数放在另一张纸上。到目前为止,我有:

Sub Macro1()
    Sheets("Sheet1").Select
    lcol = Cells(1, Columns.Count).End(xlToLeft).Column
    N = Cells(Rows.Count, 1).End(xlUp).Row

    For j = 1 To lcol
        Range(Cells(1, j), Cells(N, j)).Select
        Selection.Copy
        Sheets("Sheet2").Select
        Cells(1, 2 * j - 1).Select
        ActiveSheet.Paste

        Columns(2 * j - 1).RemoveDuplicates Columns:=1, Header:=xlNo
        nr = Cells(Rows.Count, 2 * j - 1).End(xlUp).Row
        Range(Cells(1, 2 * j), Cells(nr, 2 * j)).Select
       *Selection.FormulaArray = "=COUNTIFS(Sheet1!C[" & j & "],Sheet2!RC[-1]:R[5]C[-1])"
        Sheets("Sheet1").Select
    Next j

End Sub
  • 是我不断收到错误的地方。如何通过索引以公式表示法引用另一个工作表单元格范围。我想使用 j 来引用正确的列。

我听从了Refereing to a range of cell in another sheet 的建议,但它们引用了显式单元格。在我的例子中,我将引用显式单元格,但是通过索引引用 (j)。

注意

Sheets(2).Range("F15:AK46").Select

也给了我一个错误

【问题讨论】:

  • 我可能会为此使用字典,并且如果密钥已经存在,例如A 然后将关联值加 1。
  • 如果您最终知道最终范围是多少,只需将该范围公式设置在循环之外等于您的原始公式即可。

标签: vba excel indexing


【解决方案1】:

正如在 cmets 中提到的,使用字典是最好的方法。所以你的代码将如下所示。我不知道您希望如何打印或使用您的结果,但对于本示例,代码将创建一个名为“Results”的工作表,如果它存在,它将清除它并写入新结果:

Option Explicit
Sub CountOccurrences()
    Dim i As Long
    Dim j As Long
    Dim cnt As Long
    Dim lCol As Integer
    Dim N As Long
    Dim key As Variant
    Dim dict As Object
    Dim WS As Worksheet
    Dim WS_Result As Worksheet

    'Set objects and create a sheet to print results
    Set WS = ThisWorkbook.Worksheets("Sheet1") 'change the name of the sheet to whatever you have

    On Error GoTo Handler
    Set WS_Result = ThisWorkbook.Worksheets("Results")
    On Error GoTo 0

    WS_Result.Cells.Clear

    'Count the columns
    lCol = WS.Cells(1, WS.Columns.Count).End(xlToLeft).Column

    'Loop thru all columns and count occurrences
    For j = 1 To lCol
        'Find the last row
        N = WS.Cells(WS.Rows.Count, lCol).End(xlUp).Row

        'Create a new dictionary
        Set dict = CreateObject("scripting.dictionary")

        For i = 1 To N
            key = WS.Cells(i, j).Value
            If dict.exists(key) = False Then
                dict.Add key, 1 'key=cell value, item=count of that value
            Else
                dict(key) = dict(key) + 1
            End If
        Next i

        'Print the results
        cnt = 0
        For Each key In dict.keys
            cnt = cnt + 1
            WS_Result.Cells(cnt, (j - 1) * 2 + 1).Value = key
            WS_Result.Cells(cnt, (j - 1) * 2 + 2).Value = dict(key)
        Next key

        'Destroy the dictionary to startover
        Set dict = Nothing
    Next j

    Exit Sub
Handler:
    Set WS_Result = ThisWorkbook.Worksheets.Add
    WS_Result.Name = "Results"
    Resume
End Sub

结果快照

【讨论】:

  • @Alex 我使用了后期绑定,这使得在代码中使用字典没有问题,但是,如果您想使用字典及其方法等,更好的方法是使用 早期绑定 这意味着您需要转到 VBE 中的工具/参考并检查 Microsoft Scripting Runtime。在这种情况下,定义一个新的字典对象就像dim dict=New dictionary 一样简单,有关字典的更多信息,请访问:excelmacromastery.com/vba-dictionary
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-18
  • 2013-12-02
  • 1970-01-01
  • 2020-04-24
相关资源
最近更新 更多