#vba #excel #macros
#vba #excel #макросы
Вопрос:
Я пишу макрос в Excel, который должен удалять целые строки или добавлять строки на основе входных данных.
Теперь количество строк, подлежащих удалению, должно определяться на основе количества строк, которые уже есть, так что, скажем, если у меня есть 12 строк и ячейка рядом с суммой, равной 3, я использовал значение ячейки до сих пор, чтобы определить количество строк, подлежащих удалению.
|1(A1)| Title (B1)
|1(A2)| Title (B2)
|1(A3)| Title (B3)
|3(A4)| Sum (B4)
Вот код, который я использую (удаляемая часть, дальше пока не продвинулся):
If CInt(TextBox2.Value) = Cells(4, 1) Then
MsgBox ("Values are equal")
ElseIf CInt(TextBox2.Value) < Cells(34, 2) Then
a = Cells(4, 1) - CInt(TextBox2.Value)
For i = 1 To a
Rows(1).EntireRow.Delete
Next
End If
Проблема, которую я понял при этом, заключается в том, что ячейка суммирования, которую я использую для определения количества строк, подлежащих удалению, переместится, если я удалю строку, поэтому она больше не будет находиться в позиции (4,1) (:: A4 ::).
Мой вопрос: Есть ли способ использовать ячейку с идентификатором, который никогда бы не менялся, или динамически изменять адресное значение ячейки?
Заранее большое спасибо!
Комментарии:
1. Не уверен, но я думаю, вы можете присвоить диапазон чему-то другому, чтобы он был адресован этой переменной, которая не будет зависеть от адреса.
2. Как вы узнаете, какие строки удалять? т.Е., беря ваш пример, если есть 12 строк, и вы хотите удалить 3, как вы узнаете, какие из них удалить?
3. вы можете использовать Excel с именем Range contextures.com/xlNames01.html и затем что-то вроде
a = [nameOfYourNamedRange] - TextBox2.Value
Ответ №1:
Если вы установите ссылку на ячейку и удалите ячейки выше, чтобы ячейка переместилась вверх, ссылка на ячейку будет обновлена соответствующим образом. Смотрите следующий пример:
Function testCellRef()
Dim c As Range, i As Long
Set c = [A18]
For i = 1 To 10
Range("A" amp; i).EntireRow.Delete
Debug.Print "Deleted row " amp; i amp; ", cell Address is now " amp; c.Address
Next i
End Function
будет отображаться в немедленном окне:
Deleted row 1, cell Address is now $A$17
Deleted row 2, cell Address is now $A$16
Deleted row 3, cell Address is now $A$15
Deleted row 4, cell Address is now $A$14
Deleted row 5, cell Address is now $A$13
Deleted row 6, cell Address is now $A$12
Deleted row 7, cell Address is now $A$11
Deleted row 8, cell Address is now $A$10
Deleted row 9, cell Address is now $A$9
Deleted row 10, cell Address is now $A$9
Обратите внимание, что на последней итерации строка, которая была удалена (строка 10), находится ниже отслеживаемой ячейки, и поэтому адрес не меняется.
Обратите также внимание, что если вы замените [A18] на [A17], вы удалите строку с отслеживаемой ячейкой, а затем ссылка станет недействительной на 9-й итерации и сгенерирует ошибку при c.Address
вызове.
Ответ №2:
Вы могли бы каждый раз находить строку, содержащую формулу суммы, используя что-то вроде этого:
Columns("A").Find("=SUM", , xlFormulas, , xlRows, xlPrevious).Value
Это приведет к поиску в столбце A, начиная с последней строки и продолжая работу, и вернет значение ячейки, содержащее «=SUM». Если у вас есть более одной ячейки с этим, вам может потребоваться изменить направление или пойти другим маршрутом.
Другим вариантом было бы добавление переменной, подобной приведенному ниже примеру:
x = 0
If CInt(TextBox2.Value) = Cells(4 x, 1) Then
MsgBox ("Values are equal")
ElseIf CInt(TextBox2.Value) < Cells(34 x, 2) Then
a = Cells(4 x, 1) - CInt(TextBox2.Value)
For i = 1 To a
Rows(1).EntireRow.Delete
x = x - 1
Next
End If
Я предполагаю, что вам также нужно изменить ячейку, с которой вы сравниваете, в столбце B. При добавлении строки просто используйте x = x 1
.
Ответ №3:
Чтобы удалить строки, вы должны выполнить цикл в обратном направлении, таким образом, номера строк, которые вы предполагаете в начале цикла, останутся нетронутыми.