Проверка наличия значения в столбце, отличном от целевой строки - PullRequest
1 голос
/ 24 апреля 2020

Проще говоря, моя таблица представляет собой базу данных с элементами в столбце A и серийными номерами в столбце B. Не может быть двух одинаковых серийных номеров. Одна пользовательская форма имеет текстовые поля с элементами и серийными номерами. Как для добавления, так и для редактирования элементов используется одна и та же пользовательская форма.

Чтобы проверить, является ли серийный номер уникальным для листа, я использовал следующий код:

If Application.WorksheetFunction.CountIf(WS.Range("b4:b100"), Me.Controls("serialnumber" & i)) > j Then
   MsgBox "serial number " & Me.Controls("serialnumber" & i) & " already exists in database", vbCritical, "Error"
   Me.Controls("serialnumber" & i).SetFocus
   Exit sub
End If

перед добавлением j, я использовал 0, чтобы проверить, существует ли какое-либо вхождение, только если я использовал Add new. Тем не менее, я хотел проверить наличие дубликатов также при редактировании элемента. Это создает ошибку при редактировании, при этом в серийный номер не вносятся никакие изменения, но все равно происходит отключение счетчика и выход вспомогательного устройства.

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

IIf WS.Cells(a, 2) = Me.Controls("serialnumber" & i).Value, j = 1, j=0

«a» относится к строке, в которой находится отредактированный элемент. По сути, при редактировании список заполняется всеми элементами, и из этого listindex вызывается «a»

Проблема заключается в том, что даже если значение ячейки (a, 2) и значение текстового поля одинаковы, даже если показывая то же самое с debug.prints, оператор if, сравнивающий их, всегда оценивается как ложный. Я попытался оставить .value в обоих случаях, добавив .value к обеим сторонам уравнения, я даже объявил переменные для каждого из этих двух значений, сделал их целыми числами, сравнил их и по-прежнему отображаю false.

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

Редактировать: Вот как данные вводятся в лист.

With WS.Cells(a, "a")
    .Offset(0, 1).Value = Me.Controls("serialnumber" & i).Value
 end with

Это только числа, такие как «123456», введенные в текстовое поле серийного номера. (без кавычек)

1 Ответ

0 голосов
/ 25 апреля 2020

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

Когда вы пытаетесь присвоить значение ячейке рабочего листа, для возврата значения должна использоваться функция IIF, в частности значение, которое вы присвоили аргументу truepart или falsepart аргумент.

Согласно документации IIF 1014 *, синтаксис равен IIf ( expr, truepart, falsepart ). Таким образом, основываясь на том, является ли expr (выражение) истинным или ложным, возвращается соответствующее значение truepart или falsepart .

Важно понимать, что IIF - это функция, которая (снова для документации) Возвращает одну из двух частей, в зависимости от оценки выражения. Поскольку она возвращает значение, вы не можете присвоить значение в функции, это не то, для чего оно.

Чтобы использовать IIF в вашем контексте, правильный синтаксис будет выглядеть следующим образом:

j = IIF(WS.Cells(a, 2) = Me.Controls("serialnumber" & i).Value, 1, 0)

Основные различия заключаются в том, что мы присваиваем значение truepart или falsepart значение до j в зависимости от того, вернет ли оценка значение true или false. Я также включил круглые скобки вокруг функции, что означает, что возвращаемое значение будет присвоено чему-либо (в данном случае j. Если вы не включите круглые скобки, возвращаемое значение игнорируется. Вы можете прочитать больше об использовании скобки с функциями (и другими значениями) в Использование скобок в коде .

Оператор If...Then...Else немного отличается в том, как он работает. ( Документация здесь )

Первая строка - это оценка, If WS.Cells(a, 2) = Me.Controls("serialnumber" & i).Value Then. Пока что на самом деле нет никакой разницы в том, как мы оцениваем, но после этого мы теперь присваиваем оператор , который является другой строкой (или строками) код сделать что-то .

Итак, чтобы переписать вашу IIF функцию в операторе If...Then...Else:

If WS.Cells(a, 2) = Me.Controls("serialnumber" & i).Value Then
    j = 1    'Do this if true
Else
    j = 0    'Do this if false
End if

На новом Worksheet на новом Workbook Я протестировал весь вышеприведенный синтаксис с помощью следующих двух тестовых подпрограмм: не стесняйтесь создавать новую книгу / лист, чтобы увидеть результаты в непосредственном окне на основе значения в ячейке C5 во время запуска код. * 107 0 *

Sub TestIIFFunction()

Dim j As Long

j = IIf(Sheet1.Range("C1").Value = 1, 1, 0)

Debug.Print j

End Sub
'___________________________________________________________________________________

Sub TestIfThenElseStatement()

Dim j As Long

If Sheet1.Range("C1").Value = 1 Then
    j = 1
Else
    j = 0
End If

Debug.Print j

End Sub

Концептуальные темы Visual Basi c содержат несколько хороших тем для чтения о том, как работает код, что он делает и как его использовать.

Кому покажите визуально, что я сделал для проверки:

Sheet1 с =A1 в ячейке C5:

Sheet1 with =A1 in cell C5

И выходы из и оператор IIF function и оператор If...Then...Else:

outputs from both the IIF function and the If...Then...Else statement

...