Оптимизирующий цикл / вложенный цикл

#arrays #vba #loops #nested #nested-loops

#массивы #vba #циклы #вложенный #вложенные циклы

Вопрос:

Я прокладываю себе путь через циклы и, естественно, начал со сложного! У меня есть рабочая книга с несколькими листами. На каждом листе есть операции для завершения «виджета». Я пытаюсь просмотреть диапазон ячеек и выполнить поиск по дате, чтобы найти подходящую дату. Если эта дата совпадает, я хочу добавить стандартные часы в строку 7 этого столбца. Я смог заставить это работать с помощью принудительного кода и скопировать и вставить свой цикл для каждого столбца. Я ДЕЙСТВИТЕЛЬНО НЕ хочу делать это для всех столбцов на каждой вкладке.

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

редактировать: по сути, то, что я хочу сделать, это начать с I12, перейти к нижней части столбца, ища дату, а затем подсчитывая, сколько раз я вижу это, чтобы сложить количество часов PPC (I7). Затем перейдите к J12, выполните цикл до конца столбца, перейдите к K12, выполните цикл до конца, суммируя часы для сборки. И т.д…

Вот скриншот первых нескольких строк и столбцов, которые я пытаюсь просмотреть

 Sub Resource_Overview()
'Summary of daily tasks by worktype

'Declare the variables we'll need
Dim sht As Worksheet
Dim LastRow As Long
Dim LastColumn As Long
Dim StartCell As Range
Dim i As Double 'for counters, using double to add up decimals
Dim Assy, Solder, QC, Weld, Test, PPC As Double 'variables to hold std hours total
Dim a As Long

Assy = 0#
Solder = 0#
QC = 0#
Weld = 0#
Test = 0#
PPC = 0#

'Find Last Row and Column
Set sht = ActiveSheet
Set StartCell = Range("I12")
LastRow = sht.Cells(sht.Rows.Count, StartCell.Column).End(xlUp).Row
LastColumn = sht.Cells(StartCell.Row, sht.Columns.Count).End(xlToLeft).Column - 3 '-3 columns to not count need date or ECD info

Set sht = ActiveSheet
Set StartCell = Range("I12")
  
    For i = 12 To LastRow
        If Range("I" amp; i).Value = 44154 Then
            If Range("I" amp; 1) = "Assy" Then
                Assy = Assy   Range("I7").Value
            ElseIf Range("I" amp; 1) = "Solder" Then
                Solder = Solder   Range("I7").Value
            ElseIf Range("I" amp; 1) = "Weld" Then
                Weld = Weld   Range("I7").Value
            ElseIf Range("I" amp; 1) = "Test" Then
                Test = Test   Range("I7").Value
            ElseIf Range("I" amp; 1) = "PPC" Then
                PPC = PPC   Range("I7").Value
            ElseIf Range("I" amp; 1) = "QC" Then
                QC = QC   Range("I7").Value
            End If
        End If
    Next i
        
        
    For i = 12 To LastRow
        If Range("J" amp; i).Value = 44154 Then
            If Range("J" amp; 1) = "Assy" Then
                Assy = Assy   Range("J7").Value
            ElseIf Range("J" amp; 1) = "Solder" Then
                Solder = Solder   Range("J7").Value
            ElseIf Range("J" amp; 1) = "Weld" Then
                Weld = Weld   Range("J7").Value
            ElseIf Range("J" amp; 1) = "Test" Then
                Test = Test   Range("J7").Value
            ElseIf Range("J" amp; 1) = "PPC" Then
                PPC = PPC   Range("J7").Value
            ElseIf Range("J" amp; 1) = "QC" Then
                QC = QC   Range("J7").Value
            End If
        End If
    Next i
    
        For i = 12 To LastRow
        If Range("K" amp; i).Value = 44154 Then
            If Range("K" amp; 1) = "Assy" Then
                Assy = Assy   Range("K7").Value
            ElseIf Range("K" amp; 1) = "Solder" Then
                Solder = Solder   Range("K7").Value
            ElseIf Range("K" amp; 1) = "Weld" Then
                Weld = Weld   Range("K7").Value
            ElseIf Range("K" amp; 1) = "Test" Then
                Test = Test   Range("K7").Value
            ElseIf Range("K" amp; 1) = "PPC" Then
                PPC = PPC   Range("K7").Value
            ElseIf Range("K" amp; 1) = "QC" Then
                QC = QC   Range("K7").Value
            End If
        End If
    Next i
    
        For i = 12 To LastRow
        If Range("L" amp; i).Value = 44154 Then
            If Range("L" amp; 1) = "Assy" Then
                Assy = Assy   Range("L7").Value
            ElseIf Range("L" amp; 1) = "Solder" Then
                Solder = Solder   Range("L7").Value
            ElseIf Range("L" amp; 1) = "Weld" Then
                Weld = Weld   Range("L7").Value
            ElseIf Range("L" amp; 1) = "Test" Then
                Test = Test   Range("L7").Value
            ElseIf Range("L" amp; 1) = "PPC" Then
                PPC = PPC   Range("L7").Value
            ElseIf Range("L" amp; 1) = "QC" Then
                QC = QC   Range("L7").Value
            End If
        End If
    Next i

        For i = 12 To LastRow
        If Range("M" amp; i).Value = 44154 Then
            If Range("M" amp; 1) = "Assy" Then
                Assy = Assy   Range("L7").Value
            ElseIf Range("M" amp; 1) = "Solder" Then
                Solder = Solder   Range("M7").Value
            ElseIf Range("M" amp; 1) = "Weld" Then
                Weld = Weld   Range("M7").Value
            ElseIf Range("M" amp; 1) = "Test" Then
                Test = Test   Range("M7").Value
            ElseIf Range("M" amp; 1) = "PPC" Then
                PPC = PPC   Range("M7").Value
            ElseIf Range("M" amp; 1) = "QC" Then
                QC = QC   Range("M7").Value
            End If
        End If
    Next i
    
    Sheets("Sheet1").Select
    Range("B2") = PPC
    Range("B3") = Assy
    Range("B4") = Solder
    Range("B5") = QC
    
End Sub
  

Ответ №1:

Таким образом, вы можете создать свой диапазон:

 Range(A1:D1) -> Range(Cells(A1), Cells(D1)) -> 

Range(Cells(row number, column number), Cells(row number, column number)) -> 

Range(Cells(1, 1), Cells(1, 4))
  

Если диапазон равен «A1». Мы можем написать либо Range(Cells(1, 1), Cells(1, 1)) либо использовать ссылку на ячейку Cells(1,1) .

Для построения диапазонов с помощью цикла вы можете заменить некоторые цифры буквами, которые представляют значение цикла, т. Е. Номер столбца / строки.

Без тестирования, но я думаю, вы получите логику:

 Sub Resource_Overview()
'Summary of daily tasks by worktype

'Declare the variables we'll need
Dim sht As Worksheet
Dim LastRow As Long
Dim LastColumn As Long
Dim StartCell As Range
Dim i As, j As Long 'I always use long
Dim Assy, Solder, QC, Weld, Test, PPC As Double 'variables to hold std hours total
Dim a As Long

Assy = 0#
Solder = 0#
QC = 0#
Weld = 0#
Test = 0#
PPC = 0#

'Find Last Row and Column
Set sht = ActiveSheet
Set StartCell = Range("I12")
LastRow = sht.Cells(sht.Rows.Count, StartCell.Column).End(xlUp).Row
LastColumn = sht.Cells(StartCell.Row, sht.Columns.Count).End(xlToLeft).Column - 3 '-3 columns to not count need date or ECD info

Set sht = ActiveSheet

For i = 9 To LastColumn 'Set from which column number you want the loop to start from
    For j = 12 To LastRow
        If Cells(j,i).Value = 44154 Then
            If Cells(1,i).Value = "Assy" Then
                Assy = Assy   Cells(7,i).Value
            ElseIf Cells(1,i).Value = "Solder" Then
                Solder = Solder   Cells(7,i).Value
            ElseIf Cells(1,i).Value = "Weld" Then
                Weld = Weld   Cells(7,i).Value
            ElseIf Cells(1,i).Value = "Test" Then
                Test = Test   Cells(7,i).Value
            ElseIf Cells(1,i).Value = "PPC" Then
                PPC = PPC   Cells(7,i).Value
            ElseIf Cells(1,i).Value = "QC" Then
                QC = QC   Cells(7,i).Value
            End If
        End If
    Next j
Next i

    
Sheets("Sheet1").Range("B2") = PPC
Sheets("Sheet1").Range("B3") = Assy
Sheets("Sheet1").Range("B4") = Solder
Sheets("Sheet1").Range("B5") = QC

End Sub
  

Комментарии:

1. Это сработало отлично! Мне потребовалось несколько раз перечитывать его, но теперь я это понимаю. Большое вам спасибо, это огромная помощь!

2. Рад, что это сработало :). Не стесняйтесь спрашивать, есть ли у вас какие-либо дополнительные вопросы или хотите получить более подробную информацию. Да, когда я впервые создавал циклы, было непросто понять концепцию, но с обучением вы освоите ее!. Не стесняйтесь принимать ответ, если вы считаете, что он решил ваш вопрос / проблему Как работает принятие ответа? . Желаю вам счастливого кодирования!!

3. как только моя репутация достигнет 15, я обязательно дам ответ, подобный 1. У меня есть еще один вопрос, который включает добавление другого цикла в мой код. Когда я вызываю дату в текстовом формате (44154), я хотел бы извлечь ее, скажем, из листа 1, и чтобы ячейка B1 была датой, B2 на следующий день, B3 на следующий день и т. Д., Пока я не дойду до полной недели (7 дней). Я попытался поиграть с добавлением еще одного цикла, но он продолжал пропускать основной цикл, который мы только что решили, lol. Я думаю, что он запутался, потому что я пытаюсь ссылаться на другой лист, может быть?

4. Спасибо! Я бы предложил вам новый вопрос (и, возможно, некоторые фиктивные данные, поскольку дата может стать более сложной …), Но да, вы правы в отношении ссылки на лист. Вы не ссылаетесь на листы, которые вызывают «проблемы» / нестабильный код между листами, поскольку код не знает, на какой лист вы тоже ссылаетесь (т. Е. Cells(j,i).Value -> ws.Cells(j,i).Value ). Моя первоначальная мысль — выполнить третий цикл, в котором вы зацикливаете столбец / диапазон даты (т. Е. После For j , do For k ), а Затем проверяете Cells(j,i).Value = 44154 -> Cells(j,i).Value = Cells(k,"B").Value . В зависимости от ваших настроек, другие решения могут быть более эффективными 🙂

5. Спасибо! Я попробую поиграть с этим и задать другой вопрос, если я застряну.