Excel VBA - Сохранение результатов поиска в переменной диапазона - PullRequest
1 голос
/ 14 октября 2019

Я пытаюсь сохранить диапазоны в переменных диапазона startID, endID и endDest, но постоянно получаю сообщение об ошибке 1004 «Метод Range объекта _Global fail».

У меня есть список ссуд на контрольной странице моей рабочей книги, и все они имеют несколько строк (от 2 до 6 строк), например:

  • A |Б |C
  • кредит 1 |вещи |1,0
  • кредит 1 |вещи |1,1
  • кредит 2 |вещи |2,0
  • кредит 2 |вещи |2,1
  • кредит 2 |вещи |2.2

Вся цель состоит в том, чтобы переместить ссуду, где активная ячейка находится внизу списка. Вот с чем у меня (пока) проблемы: скажем, активная ячейка - это B2 в рабочем листе с небольшим маркированным списком выше - строка активной ячейки вместе с фиксированным индексом столбца, равным 3, указывает, что я на линии 1.1. Затем я «исправляю» 1.1 к 1 и сохраняю это целое число в currentID. Теперь я могу найти первое вхождение currentID в столбце C, а затем сохранить адрес диапазона, в котором currentID появляется в переменной диапазона startID. В этом случае я должен хранить C1 в startID.

Я прочитал, что Find возвращает диапазон. Итак, я попытался Set startID = .Range("C:C").Find(what:=currentID), но это просто сохраняет currentID 1 в startID. Затем я попытался Set startID = Range(.Range("C:C").Find(what:=currentID)) (что показано ниже в моем блоке кода), но это вызывает ошибку во время выполнения. Я также пытался добавлять и удалять периоды на случай, если я испортил оператор With, но это не помогло. есть идеи?

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

Sub ExpireLoan()
With Workbooks("1908 AUS IC Loans Recon.xlsm").Worksheets("Control Page")
Dim currentID As Integer
Dim startID As Range
Dim endID As Range
Dim endDest As Range
Dim rowCount As Integer

'find the current loan range
    currentID = Fix(.Cells(ActiveCell.Row, 3).Value)
    Set startID = Range(.Range("C:C").Find(what:=currentID))
    Set endID = Range(.Range("C:C").Find(what:=currentID + 1))
    Set endID = Range(endID.Offset(-1, 0))

'find the last row
    Set endDest = .Range("A7").End(xlDown)
    Set endDest = endDest.Offset(-1, 0)

'copy the current loan and paste into the end of the table
    rowCount = .Range(startID, endID).Count
    .Range(startID, endID).EntireRow.Copy
    .endDest.EntireRow.PasteSpecial

'set bottom border at new end of the table
    endDest.Select
    ActiveCell.Offset(0, 0).Range("A1:AF1").Borders(xlEdgeBottom).LineStyle = xlDouble

'delete rows from loan's original position above
    .Range(startID, endID).EntireRow.Delete

'set sort ID
    ActiveCell.Offset(0, 2).Value = Fix(ActiveCell.Offset(-1, 2).Value) + 1
    For i = 0 To rowCount - 2
        ActiveCell.Offset(i + 1, 2).Value = ActiveCell.Offset(i, 2).Value + 0.1
    Next

'delete loanTypeCode
    ActiveCell.Offset(0, 1).ClearContents
    For i = 1 To rowCount - 1
        ActiveCell.Offset(i, 1).ClearContents
    Next

'fix sortID
    Set sortIdRange = Range(startID, startID.End(xlDown))
    Call subtractOneFromCells

'make it red
    ActiveCell.Offset(0, 0).Range("A1:AF1").Interior.TintAndShade = 0.399975585192419
    For i = 1 To rowCount - 1
        ActiveCell.Offset(i, 17).Range("A1:P1").Interior.TintAndShade = 0.399975585192419
    Next

End With
End Sub

1 Ответ

0 голосов
/ 14 октября 2019

По моему опыту .Find может вести себя немного странно при поиске цифр. Использование xlWhole обычно исправляет это для меня, и также, когда я пробовал это на ваших примерах данных. В противном случае, если вы ищете, например, currentID = 3, .Find вернет первую ячейку с 3 в качестве подстроки. Это означает, что ячейка со значением 1.3 может быть возвращена в качестве первого вхождения 3. Попробуйте эту строку:

Set startID = .Range("C:C").Find(What:=currentID, LookAt:=xlWhole)

Чтобы отладить это, вы можете использовать F8 для последовательного перехода по коду и использоватьDebug.Print currentID и Debug.Print startID.Address, чтобы увидеть, что происходит через непосредственное окно.

Совет для более короткого кода (не обязательно всегда более читабельного) следующий: Вы можете объединить две строки, подобные этим:

Set endDest = .Range("A7").End(xlDown)
Set endDest = endDest.Offset(-1, 0)

в одну строку следующим образом:

Set endDest = .Range("A7").End(xlDown).Offset(-1, 0)

Поскольку ваша первая строка возвращает объект Range, нет необходимости сохранять его в переменной между шагами.

С другой стороны, относительно этих двух строк:

endDest.Select
ActiveCell.Offset(0, 0).Range("A1:AF1").Borders(xlEdgeBottom).LineStyle = xlDouble

Прежде всего, рекомендуется по возможности избегать использования .Select, как описано здесь: Как избежать использования Select в Excel VBA . Во-вторых, эту вторую строку трудно понять. Попробуйте использовать Resize вот так:

ActiveCell.Resize(1, 32).Borders(xlEdgeBottom).LineStyle = xlDouble
...