Есть ли такая вещь, как идентификатор ячейки?

#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:

Чтобы удалить строки, вы должны выполнить цикл в обратном направлении, таким образом, номера строк, которые вы предполагаете в начале цикла, останутся нетронутыми.