Excel VBA, если и затем не оценивать должным образом

У меня есть код ниже, и мне кажется, что проблема с утверждениями IF. В рабочей книге есть две вкладки, вкладка ALLDATA и вкладка COMP. Предполагается, что макрос заполняет список получателей (строка 1 вкладки ALLDATA), по дате (столбец A вкладки ALLDATA), по количеству (отдельные столбцы на вкладке COMP, возглавляемые строкой 1). Предполагается пропускать ячейки с 0 или пустым значением. Все ячейки с данными будут иметь положительные значения, поэтому я проверяю> 0. Вот пример, на который выглядит вкладка ALLDATA:

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

Это то, что я ожидаю, что результат будет выглядеть на вкладке COMP:

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

Вот как выглядит фактический результат:

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

И вот мой код:

Sub Payee_Date() ' ' Payee_Date Macro ' Application.ScreenUpdating = False 'Select the COMP tab Sheets("COMP").Activate 'Find the last row of the COMP tab Dim compLastRow As Long compLastRow = Cells(Rows.Count, 1).End(xlUp).Row 'Clear the COMP tab With Sheets("COMP") .Rows(2 & ":" & compLastRow).Delete End With 'Select the ALLDATA tab Sheets("ALLDATA").Activate 'Find the last row of the ALLDATA tab Dim alldataLastRow As Long alldataLastRow = Cells(Rows.Count, 1).End(xlUp).Row 'Find the last column of the ALLDATA tab Dim alldataLastColumn As Long With ActiveSheet alldataLastColumn = .Cells(1, .Columns.Count).End(xlToLeft).Column End With 'Loop through the sheet and populate the COMP tab Dim alldataColNum As Integer Dim alldataRowNum As Integer Dim compRowNum As Long Dim payee As String Dim day As String Dim amount As Double compRowNum = 2 For alldataColNum = 2 To alldataLastColumn Step 1 For alldataRowNum = 2 To alldataLastRow Step 1 If Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value > 0 And IsEmpty(Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value2) = False Then _ amount = Cells(alldataRowNum, alldataColNum).Value2 payee = Cells(1, alldataColNum).Value2 day = Cells(alldataRowNum, 1).Value2 Sheets("COMP").Activate Range("A" & compRowNum).Value = day Range("B" & compRowNum).Value = payee Range("C" & compRowNum).Value = amount Sheets("ALLDATA").Activate compRowNum = compRowNum + 1 Next alldataRowNum Next alldataColNum Application.ScreenUpdating = True ' End Sub 

Любая помощь в определении моей ошибочной логики / кода была бы весьма признательна.

У вас очень тонкая ошибка, проявляемая символом продолжения строки:

 If Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value > 0 And IsEmpty(Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value2) = False Then **_** 

Этот символ продолжения приводит к тому, что часть «then» выполняет следующий оператор, если условие теста оценивается как true и немедленно завершает блок IF. Контроль продолжается, выполняя все строки, следующие за ним, – те, которые вы намереваетесь контролировать с помощью «if / then». Снимите этот конечный «_» и добавьте «End If» непосредственно перед самым внутренним Next и он должен решить вашу проблему.

 For alldataRowNum = 2 To alldataLastRow Step 1 If Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value > 0 And IsEmpty(Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value2) = False Then amount = Cells(alldataRowNum, alldataColNum).Value2 payee = Cells(1, alldataColNum).Value2 day = Cells(alldataRowNum, 1).Value2 Sheets("COMP").Activate Range("A" & compRowNum).Value = day Range("B" & compRowNum).Value = payee Range("C" & compRowNum).Value = amount Sheets("ALLDATA").Activate compRowNum = compRowNum + 1 End If ' Add the IF block closure here Next alldataRowNum 

Логические линии

Спецификации VBA определяют концепцию логических кодовых строк.

Это включает 4 строки в модуле кода:

 If _ True _ Then _ MsgBox "Hi!" 

Но что касается VBA, это одна логическая строка кода; инструкция анализируется и интерпретируется следующим образом:

 If True Then MsgBox "Hi!" 

Полностью действующий VBA: символ подчеркивания анализируется как токен продолжения строки , а VBA интерпретирует его как находящийся на одной логической линии.

Работает для комментариев тоже (хотя это спорно является ли это хорошая вещь):

 'This comment starts here _ ...and continues there 

Нестандартные и блочные условия

Оператор conditional If поддерживает два синтаксиса:

  • Встроенный синтаксис, как указано выше:

     If True Then MsgBox "Hi!" 
  • Синтаксис блока:

     If True Then MsgBox "Hi!" End If 

При использовании синтаксиса блока каждый оператор между ключевым словом Then и токеном End If будет выполняться условно в соответствии с указанным условием.

Если какой-либо оператор следует за ключевым словом Then в той же логической строке кода , VBA пытается проанализировать инструкцию как встроенный синтаксис ; если токен {EndOfLineInstruction} (в основном, новая строка ) следует за ключевым словом Then , VBA будет анализировать условное выражение как синтаксис блока и будет ожидать встретить маркер End If до того, как он достигнет конца текущей области (например, End Sub token). Если нет токена End If , VBA выдает ошибку компиляции.


В вашем случае у вас есть:

 If someCondition Then _ DoSomething DoSomethingElse 

Который анализирует как:

 If someCondition Then DoSomething DoSomethingElse 

Но то, что вы намеревались, было:

 If someCondition Then DoSomething DoSomethingElse End If 

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

 IsEmpty(Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value2) = False 

Должно быть:

 Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value2 = "" 

Это поймает пустые ячейки и пропустит их.

Попробуйте заменить эту строку:

 If Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value > 0 And IsEmpty(Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value2) = False Then _ 

с:

 If IsNumeric(Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum)) Then 

Поскольку вы использовали «-», где нет чисел, я считаю, что проверка того, является ли значение числовой, является достаточной.

Interesting Posts

Проблема совместимости при использовании Apache POI в Android

Ошибка при выполнении действий только для ячеек формулы

Формулы CONCATENATE и TEXTJOIN / Excel / VBA

Макрос для перемещения числа с тире в новую ячейку

Посмотрите на американские и европейские форматы чисел и преобразуйте их в американский формат

Создание макроса Excel для экспорта XML в определенную папку

Найти, если символы в ячейке выделены жирным шрифтом или курсивом в java, используя api-библиотеку POI

Как вернуть ссылку на ячейку из формулы

EXCEL: изменение дат, которые происходят в диапазоне от нескольких месяцев до последнего месяца диапазона

Извлечь текст из многострочной строки, такой как строка значений ключа

Обновить текст в других листах на основе текста в Листе 1

Как я могу извлечь только текст из ячеек, которые отформатированы определенным образом. (Excel)

Список ListFillRange

Excel для Powerpoint – поиск полезного подталкивания

Объединение нескольких таблиц Excel в один

Давайте будем гением компьютера.