Я хочу создать условие ЕСЛИ, используя функцию ПРАВИЛЬНО. Он будет искать 4 последние цифры в ячейке и сравнивать их с другой ячейкой, а затем выполнять действия, если они совпадают.
Вот упрощенная версия кода, с которым я играл. Действие, которое необходимо выполнить в этом опыте, — просто отобразить счетчик в ячейке.
Public vCounter
Sub Counter()
vCounter = 0
Sheets.Add.Name = "Test"
'The cells the RIGHT function will operate from (A1, A2 and A3)
Sheets("Test").Range("A1") = "123"
Sheets("Test").Range("A2") = "456"
Sheets("Test").Range("A3") = "789"
'The cells the result of the RIGHT function will be compared to (B1, B2 and B3)
Sheets("Test").Range("B1") = "23"
Sheets("Test").Range("B2") = "456"
Sheets("Test").Range("B3") = "89"
'This cell (G3) shows the result of a RIGHT function, considering the
'last two digits in A1, as an experience; it works.
Sheets("Test").Range("G3") = Right(Sheets("Test").Cells(1, 1), 2)
For i = 1 To 3
'The RIGHT function considers the two last digits of, successively,
'A1, A2 and A3, and those are compared to, respectively,
'B1, B2 and B3. For some reason, it doesn't work here.
If Right(Sheets("Test").Cells(i, 1), 2) = Sheets("Test").Cells(i, 2) Then
vCounter = vCounter + 1
End If
Next i
'This cell (E3) shows the counter, to test whether or not the If
'condition with the RIGHT function works. By changing the contents
'of the cells I compare between each other, I can check whether or
'not it counts correctly.
Sheets("Test").Range("E3") = vCounter
End Sub
Вот что я получаю: Лист, который я получаю, когда запускаю эту процедуру
В заключение, в этом опыте ПРАВАЯ функция почему-то не работает, так как vCounter не достигает 2. Он остается на 0, показывая, что он вообще не учитывается. Из этого результата я делаю вывод, что проблема заключается в операторе IF, содержащем функцию RIGHT. Возможно, цикл For имеет к этому отношение, но я в этом сомневаюсь.
Какие-нибудь мысли?
@Tim Williams - Пожалуйста, объясните также, почему «Right $» работает иначе, чем «Right» в этом коде.
Что происходит, когда вы используете TRIM()
с RIGHT()
. Например If Right(Trim(Sheets("Test").Cells(i, 1).Value2), 2) = Trim(Sheets("Test").Cells(i, 2).Value2) Then
@dcromley - мне пришлось поискать, но похоже, что Right() возвращает тип Variant (string), но Right$() возвращает String.
Вы получите то, что хотите, если принудительно прочитаете содержимое ячейки как текст, изменив строку If
на If Right(Sheets("Test").Cells(i, 1).Text, 2) = Sheets("Test").Cells(i, 2).Text Then
. Поскольку Right
в любом случае возвращает текст, добавление Text
не обязательно для левой части сравнения.
Спасибо @Tim Williams, а также Siddharth Rout и Tom Brunberg. Тот факт, что RIGHT() возвращает строковое значение, определенно был причиной. Я был сбит с толку, потому что формат ячейки для G3 все еще отображал «Общий». Я предполагаю, что формат ячейки и тип значения - разные вещи. Я исправил проблему, поместив результат RIGHT() в функцию CSng(), и она работает. Тим, не могли бы вы предложить свой первый комментарий в качестве ответа, чтобы я мог объявить этот вопрос решенным? Если можно выбрать несколько ответов и Сиддхарт и Том предложат свои комментарии в качестве ответов, я их тоже приму.
RIGHT()
возвращает тип Variant(string)
, а RIGHT$()
возвращает String
. Технически RIGHT$()
более эффективен, чем RIGHT()
, но разница едва заметна. Основное различие между ними заключается в том, что те, у которых есть $
, не могут обрабатывать значения Null
. Лично я не использую тот, что с $
...
Несмотря на то, что вы записываете строковые значения на свой лист, Excel автоматически считает их числовыми значениями, поэтому, когда вы их читаете, вы получаете значения типа Variant/Double
.
Однако, если вы пропустите один из этих Doubles через Right()
, он вернет Variant\String
, и это сравнение между Variant\String и Variant\Double, похоже, не работает.
Некоторый тестовый код:
Sub Tester()
Dim ws As Worksheet, v As Variant
Set ws = ThisWorkbook.Worksheets("Test")
ws.Range("A1").Value = "123"
ws.Range("B1").Value = "23"
'Comparing values...
Debug.Print Right(ws.Range("A1").Value, 2) = ws.Range("B1").Value '>> False (Variant\String vs Variant\Double)
Debug.Print Right(ws.Range("A1").Value, 2) = CStr(ws.Range("B1")) '>> True (Variant\String vs Variant\String)
End Sub
Right()
вернет строковое значение, но значение из ColB читается как числовое a Double). Строка «23» и число 23 не совпадают. Хотя по какой-то причине? cstr("23")=cdbl(23)
на панели Immediate выдаетTrue