Суммирование строк над пустой ячейкой до предыдущей пустой ячейки

Здравствуйте!

Я пытаюсь создать макрос, который находит пустую ячейку в диапазоне в одном столбце и суммирует все ячейки между этой пустой ячейкой и предыдущей пустой ячейкой.

Я много искал в Интернете, и хотя другие задавали этот вопрос, я не нахожу ответы на них особенно полезными в моей ситуации, так как мне нужно, чтобы это работало через 3500+ строк.

E.g:

4  
3  
4  
BLANK 1  
2  
5  
7  
1  
BLANK 2  
1  
4  
BLANK 3

В этом случае ячейка с именем "BLANK 1" будет суммой трех предыдущих строк: 4+3+4=11
"Blank 2" будет 15 и так далее.

Диапазон "G8:G3561".

Изменить

Для быстрого ответа см. Ответ Mr_Nitrogen. Это прекрасно работает! Однако, поскольку я новичок в VBA и кодировании в целом, я не знаю, как и почему работает код.

Я очень хочу лучше понять VBA, поэтому я продолжаю эту тему (если это разрешено).
Кроме того, я хотел бы предоставить доказательства для комментаторов, что я действительно работал над этим сам и что я предпочитаю создавать свой собственный код.

Для меня важно понять, почему мой код работает или не работает, поэтому я надеюсь, что вы все еще хотите помочь мне разработать мой собственный код.

Наконец-то я нашел подход, который мне кажется логичным. Я знаю, что это не самый простой способ сделать это, но я хотел бы знать, может ли он работать.

Я написал следующий код.

Sub Sum_storage()
Dim rng As Range
Dim cell As Range
Dim cell2 As Range
Dim cell3 As Range

Range("G8").End(xlDown).Offset(1, 0).Select
Set cell = Selection
cell.Value = "temp" 'Finds the first blank cell in column G _
                     and creates a temporary value in order _
                     to find the second blank cell

Range("G8").End(xlDown).Offset(1, 0).Select
Set cell2 = Selection

cell.Offset(1, 0).Select
Set cell3 = Selection  'The range i need to sum can _
                        now be described as "cell3:cell2"

Set rng = Range(Range("cell3"), Range("cell2")) 'The code works until this point
cell2.Value = WorksheetFunction.Sum(rng)

Идея состоит в том, чтобы определить диапазон, который я хочу суммировать с несколькими переменными.
Моя проблема заключается в попытке сослаться на эти переменные (и установить их более простым способом, чем использование .Offset).

Просто невозможно установить диапазон (rng) на основе двух ранее установленных диапазонов?

Если это возможно, следующим шагом для меня будет создание какого-то цикла, который мог бы заставить это работать для всех 3500+ строк.


person DirtyDeffy    schedule 19.04.2018    source источник
comment
comment
Добро пожаловать в StackOverflow. Обратите внимание, что это не бесплатная служба написания кода. Тем не менее, мы стремимся помочь коллегам-программистам (и кандидатам) в написании собственного кода. Прочтите справочные разделы Как задать хороший вопрос. Вы также можете принять участие в туре и получить за это значок. После этого обновите свой вопрос кодом VBA, который вы написали до сих пор, чтобы выполнить задачи, которые вы хотите выполнить. Мы будем ждать вас здесь. Готов помочь вам доработать ваш код.   -  person Ralph    schedule 19.04.2018
comment
Если вы проявите некоторые усилия, пытаясь что-то сделать, я буду более чем готов помочь вам исправить ваш код, но это не бесплатная служба кода, поэтому, пока я не увижу реальных усилий. Существует множество постов, где вы можете найти несколько необходимых вам функций. Начните с поиска первой пустой ячейки ссылка и продолжайте. Если вы застряли, добавьте свой код в OP, и мы поможем вам перейти к следующему шагу. Удачи   -  person T. Nesset    schedule 19.04.2018
comment
@Ralph Спасибо за ваш комментарий. Мне очень жаль, что я, очевидно, задал плохой вопрос и пропустил некоторые правила этикета с этим. Тем не менее, я приложил некоторые усилия, чтобы попытаться решить эту проблему самостоятельно. Причина, по которой я не предоставил примеры кода и тому подобное, заключается в том, что у меня есть ощущение, что они используют совершенно неправильный подход. Я поработаю над ними еще немного и обновлю пост в ближайшее время. Для меня очень важно сказать, что я никогда не ожидал, что люди предоставят мне полное кодовое решение. Однако, читая пост сейчас, я понимаю, почему заставил вас поверить в это.   -  person DirtyDeffy    schedule 19.04.2018
comment
@T.Nesset Спасибо за ваш комментарий. Я хотел бы, чтобы вы прочитали мой комментарий к Ральфу, так как он адресован и вам. Ссылка, которую вы мне дали, интересна, так как она дала мне идею, над которой я буду работать. Я думаю, что причина, по которой я не нашел других ответов на подобные вопросы полезными, заключается в том, что они пытаются дать очень конкретный ответ на конкретную проблему в конкретной ситуации. Мне нужно разбить проблему на более мелкие части и получить представление об этих битах, в чем мне помогает ваша ссылка. Так что спасибо за это.   -  person DirtyDeffy    schedule 19.04.2018
comment
@JoeBerg Не волнуйтесь, даже если вы полностью ошибаетесь в своем подходе, это не имеет значения. Люди здесь любезно помогут даже в этом, если ОП продемонстрирует свои усилия.   -  person Pᴇʜ    schedule 19.04.2018
comment
@JoeBerg, как сказал pᴇʜ, даже неправильный подход хорош для публикации, и мы можем дать вам несколько советов о том, что можно улучшить или как вы можете переписать его в другом подходе. Люди здесь, чтобы помочь, но не раньше, чем будут предприняты реальные усилия в операционке. Даже если вы не можете понять, с чего начать, дайте ссылку на какой-нибудь пост, который вы просматривали, чтобы показать, что вы пытались. Рад, что ссылка, которую я отправил, может вдохновить вас, и, как я уже сказал, я буду рад помочь, если вы застрянете. Каждая небольшая функция, которая вам понадобится для создания этого кода, находится в StackOverflow, просто найдите определенные части кода, а затем объединить его вместе. :)   -  person T. Nesset    schedule 19.04.2018


Ответы (2)


Это не так сложно сделать с циклом for, может быть, что-то вроде

lastrow = Cells(Rows.Count, "G").End(xlUp).Row
firstrow = 8
TempTotal = 0
for x = firstrow to lastrow + 1
    If Cells(x, "G") <> "" Then
        TempTotal = TempTotal + Cells(x, "G")
    Else:   Cells(x, "G") = TempTotal
            Cells(x, "G").Interior.ColorIndex = 4
            TempTotal = 0
    End if
    Next x

Я сделал редактирование, чтобы сделать его немного проще

Логика кода:

  1. Определите последнюю строку с данными в столбце "G"
  2. Двигайтесь вниз по ячейке, пока эта строка
  3. Если в ячейке есть значение, добавьте его к временной сумме.
  4. Если он пуст, введите временную сумму и сбросьте tempTotal до нуля.

    1. Это первая строка, в которой мы выбираем самую последнюю последнюю ячейку в столбце «G», используем для нее End(xlup), чтобы перейти к последней ячейке с данными, и используем .row, чтобы получить номер строки этой ячейки.

    2. Настройте цикл For, который многократно запускает код между строками «for» и «next x», увеличивая значение x от «firstrow» до «lastrow + 1» каждый раз, когда он повторяется (так, если firsrow равен 1, а lastrow равен 1). 100), то он запустит код 100 раз с x = 1,2,3,4,5 и т. д.)

    3. это оператор «если», «‹>» означает не равно, поэтому мы говорим, что если ячейка в строке x, столбец «G» не равна «», которая является пустой строкой (или ничем), тогда мы делаем следующая строка (добавьте ее значение в tempTotal)
    4. если утверждение «Если» неверно (если ячейка пуста), то мы делаем то, что находится под «Другим», и делаем эту ячейку равной TempTotal, меняем ее цвет на зеленый (4 — это цветовой код, они варьируются от 1 до 50 ) и сбросьте temptotal до 0.
person Jerome Paddick    schedule 19.04.2018
comment
Поскольку Stack Overflow не является бесплатной службой написания кода, отвечать на вопросы - плохая практика, поскольку ОП не продемонстрировал никаких попыток решить эту проблему самостоятельно. - person Pᴇʜ; 19.04.2018
comment
Справедливое замечание, все еще немного глупо голосовать за приемлемый ответ. - person Jerome Paddick; 19.04.2018
comment
Спасибо за ваш ответ - это работает красиво! Я ценю тот факт, что вы ответили на мой вопрос, хотя он был плохим. Сожалею, что ваш ответ получил отрицательную оценку. - person DirtyDeffy; 19.04.2018
comment
Не беспокойся, чувак, рад помочь. Я могу немного лучше объяснить логику своего кода, если хотите. - person Jerome Paddick; 19.04.2018
comment
@Mr_Nitrogen Я бы очень этого хотел, если предложение все еще в силе? :) - person DirtyDeffy; 20.04.2018
comment
@Mr_Nitrogen Спасибо - это, безусловно, полезно! :) - person DirtyDeffy; 23.04.2018

Вы были на правильном пути, используя End(xlDown).

Это должно быть намного быстрее, чем цикл по всем ячейкам, потому что он переходит к следующей пустой ячейке и суммирует через WorksheetFunction.Sum.

Option Explicit

Public Sub DoMyStuff()
    Dim ws As Worksheet
    Set ws = Worksheets("Tabelle8") 'define your worksheet here

    Dim FirstCell As Range
    Set FirstCell = ws.Range("G8")

    Dim VeryLastCell As Range 'get very last cell as stop criteria
    Set VeryLastCell = ws.Cells(ws.Rows.Count, "G").End(xlUp)

    Do
        Dim LastCell As Range
        If FirstCell.Offset(1) = vbNullString Then 'test if there is only one cell to sum
            Set LastCell = FirstCell
        Else
            Set LastCell = FirstCell.End(xlDown)
        End If

        With LastCell.Offset(1, 0) 'this is the cell we want to write the sum
            .Value = Application.WorksheetFunction.Sum(ws.Range(FirstCell, LastCell))
            .Interior.Color = RGB(255, 0, 0)
        End With

        Set FirstCell = LastCell.Offset(2, 0)

    Loop While FirstCell.Row < VeryLastCell.Row
End Sub
person Pᴇʜ    schedule 19.04.2018
comment
Работает отлично - спасибо! К сожалению, я не могу принять ваш ответ в дополнение к ответу Mr_Nitrogen. Но я очень благодарен, что вы нашли время, чтобы опубликовать ответ :) - person DirtyDeffy; 20.04.2018
comment
@JoeBerg Все в порядке, я не ищу очки. • Если скорость имеет значение (например, у вас много строк), это будет быстрее. Например. для 500 строк это заняло в среднем 90,80 мс, тогда как перебор всех ячеек заняло 103,02 мс. Таким образом, чем больше у вас строк и чем меньше пустых ячеек, тем быстрее должен быть этот код по сравнению с другим циклом. Эта разница может не иметь значения для вас, но иногда имеет значение. Зависит от вашего количества данных. - person Pᴇʜ; 20.04.2018
comment
Я полностью согласен. У меня есть другие коды, где важна скорость, но в данном конкретном случае это не так. Однако приятно лучше понять, что требует времени при выполнении кода. Так что спасибо тебе :) - person DirtyDeffy; 20.04.2018