Как применить код ко всем следующим строкам

#excel #vba

#excel #vba

Вопрос:

У меня есть этот код, но он работает только для моей первой строки. Предполагается посмотреть, установлен ли флажок на B, C или D, и если это так, дата имя пользователя автоматически заполнят F и G.

вот изображение моей таблицы:

введите описание изображения здесь

Вот как выглядит мой код:

 Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Range("B2") Or Range("C2") Or Range("D2") = True Then
Range("G2").Value = Environ("Username")
Range("F2").Value = Date
Else
Range("F2:G2").ClearContents
End If
End Sub
  

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

1. Что именно вы хотите запустить для проверки / обновления строки? Обычно вы используете Change событие для чего-то подобного, а не SelectionChange

2. У меня есть флажки, как вы видите, которые связаны с ячейками. Когда один из них проверяется в строке, я хочу, чтобы столбец F, который находится в той же строке (Дата), автоматически заполнялся меткой времени, и я хочу, чтобы столбец G, который также находится в той же строке (идентификатор), указывал имя пользователя () пользователя Windows… Я не знаю, ответил ли я на ваш вопрос — я очень новичок в VBA. Спасибо!

3. Вы жестко запрограммировали диапазоны, поэтому это будет работать только для строки 2, как вы видели. ‘Target’ внутри функции — это вызывающая ячейка из изменения выбора, поэтому вы можете использовать что-то вроде: Range («B» amp; Target.Row)

4. @Tragamor Да, я жестко запрограммировал диапазоны. Как мне заставить код следовать за новостными строками? Как насчет столбцов G и F? Диапазон («G» amp; Target. Строка) тоже? Спасибо!

Ответ №1:

Введите этот код в обычный модуль, установите все флажки и щелкните правой кнопкой мыши >> назначить макрос, затем выберите ReviewRows .

Проверка будет выполняться при каждом нажатии флажка — немного накладных расходов, поскольку все строки будут проверены, но это не должно иметь большого значения.

 Sub ReviewRows()
    Dim n As Long
    For n = 1 To 100 'for example
        With Sheet1.Rows(n)
            If Application.CountIf(.Cells(2).Resize(1, 3), "TRUE") > 0 Then
                If Len(.Cells(6).Value) = 0 Then 'only enter if currently empty?
                    .Cells(6) = Date
                    .Cells(7) = Environ("Username")
                End If
            Else
                .Cells(6).Resize(1, 2).ClearContents
            End If
        End With
    Next n
End Sub
  

Если вы хотите быть более точным, тогда Application.Caller вам будет указано имя флажка, который был нажат, и вы можете использовать его, чтобы найти соответствующую строку для проверки с помощью linkedCell .

 Sub ReviewRows()
    Dim n As Long, shp As CheckBox, c As Range, ws As Worksheet
    
    Set ws = ActiveSheet
    On Error Resume Next 'ignore error in case calling object is not a checkbox
    Set shp = ActiveSheet.CheckBoxes(Application.Caller) 'get the clicked checkbox
    On Error GoTo 0 'stop ignoring errors
    
    If Not shp Is Nothing Then          'got a checkbox ?
        If shp.LinkedCell <> "" Then    'does it have a linked cell ?
            With ws.Range(shp.LinkedCell).EntireRow
                If Application.CountIf(.Cells(2).Resize(1, 3), "TRUE") > 0 Then
                    If Len(.Cells(6).Value) = 0 Then 'only enter if currently empty?
                        .Cells(6) = Date
                        .Cells(7) = Environ("Username")
                    End If
                Else
                    .Cells(6).Resize(1, 2).ClearContents
                End If
            End With
        End If 'has linked cell
    End If 'was a checkbox
End Sub

  

Однако эта оценка зависит от точного расположения вашего флажка

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

1. Он работает отлично. Единственная небольшая проблема, с которой я сталкиваюсь, заключается в том, что каждый раз, когда я устанавливаю флажок, он добавляет имя пользователя дату (как и ожидалось), но курсор мыши буферизуется примерно на 3 секунды и одновременно замораживает excel. Это потому, что он повторяется более 100 раз? (для n = от 1 до 100). Что я могу сделать, чтобы это исправить? Мой компьютер довольно мощный, поэтому его замораживание таким образом пугает.. Я не хочу видеть, как это будет реагировать в рабочем офисе! Еще раз спасибо!!

2. это около 100 строк, но как только я устанавливаю флажок, он должен просто добавить дату имя пользователя в ту же строку, а затем выйти из цикла ..!!

3. Как вы добавили флажки? Все ли они имеют уникальные имена?

4. Я добавил флажок для каждой ячейки и подключил каждый отдельный флажок к соответствующей ячейке, используя Format Control -> Ссылка на ячейку

5. Смотрите Мое обновление выше — должно работать до тех пор, пока все ваши флажки имеют связанную ячейку

Ответ №2:

Вам предстоит пройти долгий путь! К сожалению, If Range("B2") Or Range("C2") Or Range("D2") = True Then восстановлению не подлежит. На самом деле, вся ваша концепция такова.

Начните с концепции: технически говоря, флажков нет на рабочем листе. Они находятся на слое, который накладывается на рабочий лист. Они не вызывают событие рабочего листа и не реагируют на события рабочего листа. Хорошо, что у них есть свои собственные.

If Range("B2") Or Range("C2") Or Range("D2") = True Then объединяет Range с Range.Value . Один — это объект (ячейка), другой — одно из свойств объекта. Итак, чтобы вставить смысл в ваш синтаксис, он должен был бы читать, например, If Range("B2").Value = True Or Range("C2").Value = True Or Range("D2").Value = True Then . Однако это не сработает, потому что триггер неверен. Событие Worksheet_Change не срабатывает, когда флажок изменяет значение ячейки, а событие SelectionChange слишком распространено, чтобы позволить ему выполняться без разбора в надежде, что иногда оно будет правильным (например, сломанные часы, которые показывают правильное время два раза в день).

Поэтому ответ заключается в том, чтобы зафиксировать событие щелчка флажка.

 Private Sub CheckBox1_Click()
    If CheckBox1.Value = vbTrue Then
        MsgBox "Clicked"
    End If
End Sub
  

Все, что вы хотите сделать, когда флажок установлен, должно быть сделано там, где теперь отображается сообщение. Вы также можете предпринять действия, когда флажок снят.

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

1. Привет, спасибо за ваши подробные ответы и пояснения. Но я хотел бы сказать… Флажки связаны с ячейками под ними. Итак, если проверить, скажем, B2, тогда ячейка B2 = True. Разве мы не можем что-то с этим сделать? Я не совсем понял цель. Адресный код также… Извините, я новичок в VBA. Обычно я занимаюсь только веб-разработкой!

2. 999 извинений! Я опубликовал неправильную процедуру — теперь изменено. Связанная ячейка принимает Value значение флажка, но изменение не вызывает события. Лучше пить прямо из колодца. Процедура запускается при нажатии флажка, указанного в его названии. Вы получаете его Value одновременно со связанной ячейкой.

3. Но он по-прежнему не отвечает на мой первоначальный вопрос. Я не хочу жестко кодировать каждый отдельный флажок, поэтому я связал их с ячейкой. Каждый флажок связан со своей собственной ячейкой. Как заставить каждую строку следовать одному и тому же коду?

4. «Жесткий код» не похож на правильное слово для меня. Но да, вам нужно будет написать процедуру события для каждого флажка. Если вам просто нужна временная метка, снимите флажки и используйте событие Worksheet_Change для запуска кода. Вам нужно будет определить, что вызывает временную метку.