简体   繁体   English

创建其条目是其他范围VBA的条目总和的新范围

[英]Create new range whose entries are the entry-wise sums of other ranges VBA

I'm looking for a way to read in multiple rows and create a new row whose entries are the sums of the entries in each row. 我正在寻找一种方法来读取多行并创建一个新行,其条目是每行中条目的总和。 I'm doing this in the context of a .Find, where I have a large 33405 x 16 spreadsheet, and once VBA find all the rows containing any of the strings from my strSearch() array, I want to create a new row summing each cell across all the rows found. 我是在.Find的上下文中执行此操作的,这里有一个33405 x 16的大型电子表格,一旦VBA从strSearch()数组中找到了包含任何字符串的所有行,我想创建一个新的行求和找到的所有行中的每个单元格。

Right now I have a way to do this that accesses each cell at a time, but it's very slow (15 minutes). 现在,我有一种方法可以一次访问每个单元,但是非常慢(15分钟)。 I'd like to be able to manipulate whole rows at once. 我希望能够一次操纵整个行。 Perhaps something along the lines of 也许与

  1. Find first instance of first element in strSearch(), copy in the entire row 在strSearch()中查找第一个元素的第一个实例,并复制到整行中
  2. Copy this row to new row at bottom 将此行复制到底部的新行
  3. From there, find first instance of second element in str(Search), copy in entire row 从那里,在str(Search)中找到第二个元素的第一个实例,复制整行
  4. Replace the last row with the sum of itself and this new row 用自身和新行的总和替换最后一行
  5. Repeat until last element in strSearch() 重复直到strSearch()中的最后一个元素
  6. From this spot, repeat the process from the first element in strSearch(), continuing until the bottom of the range. 从该位置开始,从strSearch()的第一个元素开始重复该过程,直到该范围的底部。

The current code I have is below. 我当前的代码如下。 What this does is find the row number of every instance of the first string in strSearch(), and copies those rows to the bottom. 这是在strSearch()中找到第一个字符串的每个实例的行号,然后将这些行复制到底部。 Then it finds the row number for every instance of string 2 in strSearch() and adds those rows to the rows at the bottom, cell by cell (so the last row in the spreadsheet is now the entrywise sum of the rows corresponding to the last instance of string1 and string2). 然后,它在strSearch()中找到字符串2的每个实例的行号,并将这些行逐个单元地添加到底部的行中(因此电子表格中的最后一行现在是与最后一个行相对应的行的逐项求和string1和string2的实例)。 The first five cells in each row of the spreadsheet are strings specifying locations, and then the remaining cells in an row are longs. 电子表格每行中的前五个单元格是指定位置的字符串,然后一行中的其余单元格为long。

Private Function Add_Industries(sheetName As String, strSearch() As Variant, yearsNaicsData As Integer, newIndustry As Long)

Application.ScreenUpdating = False

Dim i As Integer, _
    j As Integer
Dim rngSearch As range
Dim firstAddress As String

Worksheets(sheetName).Activate
With Worksheets(sheetName).range("D:D")
    For k = 0 To UBound(strSearch)
    j = 0
    Set rngSearch = .Find(strSearch(k), .Cells(1), xlValues, xlWhole)                        
    If Not rngSearch Is Nothing Then
        firstAddress = rngSearch.Address
        Do
            If k = 0 Then                                                           'Add the first listings
                Cells(ActiveSheet.UsedRange.Rows.Count + 1, 1) = Cells(rngSearch.Cells.Row, 1)
                Cells(ActiveSheet.UsedRange.Rows.Count, 2) = Cells(rngSearch.Cells.Row, 2)
                Cells(ActiveSheet.UsedRange.Rows.Count, 3) = Cells(rngSearch.Cells.Row, 3)
                Cells(ActiveSheet.UsedRange.Rows.Count, 4) = newIndustry
                Cells(ActiveSheet.UsedRange.Rows.Count, 5) = Cells(rngSearch.Cells.Row, 5)
                For i = 6 To 6 + yearsNaicsData - 1
                    Cells(ActiveSheet.UsedRange.Rows.Count, i) = Cells(rngSearch.Cells.Row, i)
                Next
            Else                                                                    'Sum up the rest of the listings
                For i = 6 To 6 + yearsNaicsData - 1
                    Cells(ActiveSheet.UsedRange.Rows.Count - (254 - j), i) = Cells(ActiveSheet.UsedRange.Rows.Count - (254 - j), i) + Cells(rngSearch.Cells.Row, i)
                Next
                j = j + 1
            End If

            Set rngSearch = .FindNext(rngSearch)                                    'Find the next instance
        Loop While Not rngSearch Is Nothing And rngSearch.Address <> firstAddress
    End If
Next
End With

In an attempt to read and manipulate whole rows, I've messed around with collections, but this code doesn't work very well, and I don't know what to put in the Else (k <> 0) statement to get the results I want. 为了读取和操作整个行,我弄乱了集合,但是这段代码不能很好地工作,而且我不知道在Else(k <> 0)语句中放入什么来获取我想要的结果。

Private Function Add_Industries2(sheetName As String, strSearch() As Variant, yearsNaicsData As Integer, newIndustry As Long)

Application.ScreenUpdating = False

Dim i As Integer, _
    j As Integer, _
    k As Integer
Dim rngSearch As range
Dim cl As Collection
Dim buf_in() As Variant
Dim buf_out() As Variant
Dim val As Variant
Dim firstAddress As String

Worksheets(sheetName).Activate
With Worksheets(sheetName).range("D:D")

k = 0
Set rngSearch = .Find(strSearch(k), .Cells(1), xlValues, xlWhole)
If Not rngSearch Is Nothing Then
    firstAddress = rngSearch.Address
    Set cl = New Collection
    Do
        For k = 0 To UBound(strSearch)
            Set buf_in = Nothing
            buf_in = Rows(rngSearch.Row).Value
                If k = 0 Then
                    For Each val In buf_in
                        cl.Add val
                    Next
                Else
                    'Somehow add the new values from buff_in to the values in the collection?
                End If
            ReDim buf_out(1 To 1, 1 To cl.Count)

            Rows(ActiveSheet.UsedRange.Rows.Count + 1).Resize(1, cl.Count).Value = buf_out
            Cells(ActiveSheet.UsedRange.Rows.Count, 4) = newIndustry

            If k + 1 <= UBound(strSearch) Then
                Set rngSearch = .Find(strSearch(k + 1), .Cells(rngSearch.Cells.Row), xlValues, xlWhole)
            Else
                Set rngSearch = .Find(strSearch(0), .Cells(rngSearch.Cells.Row), xlValues, xlWhole)
                k = 0
            End If
        Next
    Loop While Not rngSearch Is Nothing And rngSearch.Address <> firstAddress
End If
End With
End Function

Sorry if this is vague, hopefully there's a faster way to do this! 抱歉,如果不清楚,希望有更快的方法! I'm fairly new to VBA, but I've searched all over google and stackoverflow for about a week to try to find a similar question/answer to no avail. 我对VBA还是很陌生,但是我已经在整个Google和stackoverflow上搜索了大约一周的时间,试图找到一个类似的问题/答案无济于事。

Let's try something easy. 让我们尝试一些简单的事情。

Instead of create an array and use VBA you can use just formulas. 除了创建数组并使用VBA,您还可以仅使用公式。 Lets try something like this: 让我们尝试这样的事情:

  1. Create an extra column for each string in your array [Column 17, 18, 19 ...]. 为数组中的每个字符串创建一个额外的列[Column 17,18,19 ...]。
  2. Add the formula: =ISERROR(IF(FIND(<STRING_VALUE>,<STRING_TO_SEARCH>),"X"),"") 添加公式: =ISERROR(IF(FIND(<STRING_VALUE>,<STRING_TO_SEARCH>),"X"),"")
  3. To sum the value you can create a new table like this: 要对值求和,可以创建一个新表,如下所示:

Example: 例:

Column 1                Column 2
<STRING_VALUE_1>        =SUMIF(Columns(17),"X",<Column_To_SUM>)
<STRING_VALUE_2>        =SUMIF(Columns(18),"X",<Column_To_SUM>)
<STRING_VALUE_3>        =SUMIF(Columns(19),"X",<Column_To_SUM>)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM