решения Luuklag является легко реализовать и будет хорошо работать обеспечивая пользователь никогда не помещает «Y» в неправильном колонке.
Рассмотрите: пользователь вводит «Y» в ячейку F20, формула в ячейке G20 отображает «N». Затем пользователь понимает, что совершил ошибку и ввел «Y» в ячейку G20. Формула в ячейке F20 была перезаписана, поэтому будет отображаться «Y».
Вам нужна рутина Sheet_Change
или Change event
.
Создайте новую книгу и откройте редактор Visual Basic. Слева вы увидите что-то вроде:
- VBAProject (Test.xlsm)
- Microsoft Excel Objects
Sheet1 (Sheet1)
Sheet2 (Sheet2)
Sheet3 (Sheet3)
ThisWorkbook
Если любой из дефис является плюсом, щелкните его, чтобы развернуть список.
Дважды щелкните Sheet2 (Sheet2)
, чтобы отобразить область кода для листа «Sheet2». Скопируйте следующее в эту область кода:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Debug.Print Target.Address & "=" & Target.Value
End Sub
Перейдите в Excel и введите несколько значений в каждый рабочий лист. Переключитесь обратно в Visual Basic и Immediate Window будет содержать что-то вроде:
$E$4=a
$E$7=b
$H$7=g
$H$4=h
Ни одно из значений, введенных в «Лист1» или «Лист3» не будет записан. Для каждого значения, введенного в «Лист2». У вас будет строка, показывающая адрес ячейки и ее новое значение.
Существует аналогичный Workbook_SheetChange
, который идет в области ThisWorkbook
кода и который бы записать изменения для всех рабочих листов, но я думаю, что немного проще Worksheet_Change
процедура будет достаточно для ваших нужд.
С помощью процедуры Worksheet_Change
вы можете указать, что если ячейка в столбце F становится «Y», соответствующая ячейка в столбце G становится «N». И наоборот.
Есть два осложнения:
- С
Worksheet_Change
, Target
является диапазон, который может включать в себя несколько ячеек, если копии пользовательских блока. Я использовал For Each CellCrnt In Target
для разделения диапазона на отдельные ячейки.
- У вас есть девять пар столбцов. Можно было бы кодировать каждую пару отдельно, но это было бы много кода. Я использовал два массива. Первый массив содержит все столбцы, в которые может быть введено значение, а во втором - соответствующие столбцы. Я считаю, что правильно записал номера столбцов, но их легко изменить, если я допустил какие-либо ошибки. Использование таких массивов означает, что больше пар столбцов можно добавить, просто добавив значения в массивы, а столбцы не должны быть смежными.
Пробуйте мой код и возвращайтесь с вопросами по мере необходимости.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim CellCrnt As Range
Dim ColCrnt As Long
Dim ColsA As Variant
Dim ColsB As Variant
Dim Found As Boolean
Dim InxCols As Long
Dim RowCrnt As Long
ColsA = Array(6, 8, 10, 13, 15, 17, 20, 22, 24, 7, 9, 11, 14, 16, 18, 21, 23, 25)
ColsB = Array(7, 9, 11, 14, 16, 18, 21, 23, 25, 6, 8, 10, 13, 15, 17, 20, 22, 24)
For Each CellCrnt In Target
ColCrnt = CellCrnt.Column
Found = False
' Look along ColsA for the column of the cell just changed
For InxCols = LBound(ColsA) To UBound(ColsA)
If ColsA(InxCols) = ColCrnt Then
Found = True
Exit For
End If
Next
If Found Then
' The cell is within a controlled column
If UCase(CellCrnt.Value) = "Y" Or UCase(CellCrnt.Value) = "N" Then
RowCrnt = CellCrnt.Row
' Good value
CellCrnt.Font.Color = RGB(0, 0, 0) ' Set Black in case of earlier error
With Cells(RowCrnt, ColsB(InxCols))
.Font.Color = RGB(0, 0, 0) ' Set Black in case of earlier error
If UCase(CellCrnt.Value) = "Y" Then
.Value = "N"
Else
.Value = "Y"
End If
End With
Else
' Bad value
CellCrnt.Font.Color = RGB(255, 0, 0) ' Set Red to indicate error
End If
End If
Next
End Sub
Почему не просто заполнить все эти клетки с помощью оператора IF: Пример для G2: IF (F2 = «», «», N) А потом F2 вы положили в той же формуле, но со ссылкой на G2. Итак, теперь, как только значение будет введено в любую из ячеек, оно заменит формулу в этой ячейке, а другая ячейка получит значение N. – Luuklag