Код VBA, необходимый для очистки содержимого ячейки AQ при изменении значения ячейки D; Microsoft Excel для Office 365 MSO 32-разрядная версия

448
MJS

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

Я использовал приведенную ниже формулу в попытке очистить содержимое ячейки AQ при изменении значения ячейки D (в той же строке). В настоящее время содержимое очищается только в AQ, когда значение в ячейке D изменяется на 1 (предположительно, из-за строки «If Target = 1 Then». Что я использую вместо «1», так что все изменяется от любого значения до любое значение, будет инициировать инструкцию ClearContents для ячейки AQ?

Option Explicit  Private Sub Worksheet_Change(ByVal Target As Range) If Not Intersect(Target, Range("D7:D506")) Is Nothing Then If Target = 1 Then Range("AQ" & Target.Row).ClearContents End If End If End Sub 
0
Почему вы тестируете `If Target = 1`? Почему бы просто не вынуть его и не выполнить `` If Not Intersect (Target, Range ("D7: D506")), то есть Nothing Then`` ... `` Range ("AQ" & Target.Row) .ClearContents``? Scott 5 лет назад 0
Привет Скотт, я только что понял это. Я должен был посмотреть на ваш ответ час назад! Чтобы ответить на ваш вопрос: это проблема, когда один человек плагиат весь свой код из других подобных примеров в Интернете. Простые решения не очевидны для непосвященных. В то время как у меня есть вы, есть ли код, который я мог бы добавить, чтобы предотвратить очистку AQ, если значение D изменяется на то же значение. (т.е. D = 1, затем я снова вводю D = 1). В настоящее время код не может различить истинное изменение значения (например, от 1 до 2) и просто повторный ввод того же значения (например, от 1 до 1). MJS 5 лет назад 0
Интересный вопрос. У меня довольно мало опыта работы с `Worksheet_Change`. Я полагаю, что вы экспериментально убедились, что подпрограмма `Worksheet_Change` вызывается, даже когда ячейка" изменяется "на ее текущее значение? В этом случае я подозреваю, что вам не повезло (любой, кто знает лучше, не стесняйтесь поправлять меня!). Единственное, что я могу предложить, - это сохранить резервную копию столбца `D` и сравнить« новое »значение с сохраненной копией. Scott 5 лет назад 0
Спасибо за помощь @Scott MJS 5 лет назад 0
Спасибо @Christofer Вебер. У меня были некоторые проблемы с вашим кодом, но в то же время я получил (казалось бы) работоспособное решение на другом форуме, так что, надеюсь, сейчас это не понадобится. Но спасибо за ваше время и усилия. MJS 5 лет назад 0

1 ответ на вопрос

0
Christofer Weber

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

Затем, когда происходит изменение, мы сравниваем новое значение этой ячейки со старым значением в коллекции и только если они не совпадают, очищают содержимое AQ. Что-то вроде:

Public coll As New Collection  Private Sub Worksheet_SelectionChange(ByVal Target As Range) Dim cel As Range Set coll = New Collection If Not Intersect(Target, Range("D7:D506")) Is Nothing Then For Each cel In Target coll.Add cel.Value, cel.Address Next cel End If End Sub  Private Sub Worksheet_Change(ByVal Target As Range) If Not Intersect(Target, Range("D7:D506")) Is Nothing Then If Not Target.Value = coll(Target.Address) Then Range("AQ" & Target.Row).ClearContents End If End If End Sub 

Редактирование обновлено для работы при выборе нескольких ячеек.

Очевидно, что если вы измените значение Range("D7:D506")без фактического выбора ячейки, этот код выдаст ошибку.

Если подумать, вы можете редактировать несколько ячеек одновременно, если удаляете значение. Тогда этот код также выдаст ошибку. Но мы можем обойти это, используя тот же подход, Worksheet_Changeчто и в Worksheet_SelectionChange:

Private Sub Worksheet_Change(ByVal Target As Range) Dim cel As Range If Not Intersect(Target, Range("D7:D506")) Is Nothing Then For Each cel In Target If Not cel.Value = coll(cel.Address) Then Range("AQ" & cel.Row).ClearContents End If Next cel End If End Sub 
(1) Хорошо. Я думал о том, чтобы сохранить копию столбца «D» где-то еще на рабочем листе (например, столбец «AD»); хранение в памяти VBA кажется более безопасным. (2) Между заголовком вопроса и строкой «Если не пересекается (цель, диапазон (« D7: D506 »))) есть строка Ничто тогда», представляется, что пользователь касается только изменений *** в ** столбце «D». `; * в частности, в диапазоне` D7: D506`. Поэтому я хотел бы предложить, чтобы ваша процедура выполнялась не для каждого элемента в цели, а для каждого элемента в точке пересечения (цель, диапазон («D7: D506»)) ». Scott 5 лет назад 1
Помещение пересечения в условие цикла? Никогда не думал об этом. Мне это нравится! Очень эффективный. Christofer Weber 5 лет назад 0

Похожие вопросы