Как объявить гибкую переменную для книги? - PullRequest
1 голос
/ 26 сентября 2019

Я хотел бы как-то объявить динамические переменные книги, чтобы я мог изменять имена файлов книги, не вызывая ошибок.Моя первоначальная мысль состояла в том, чтобы использовать Set Variable = ActiveWorkbook, но, похоже, это приводит к некоторым специфическим ошибкам:

    Set WkBk1 = ActiveWorkbook

    MsgBox (WkBk1.Name)
    WkBk1.Worksheets(1).Select

Приведенный выше код прекрасно работает сам по себе.После этого, в той же процедуре, я открываю новую книгу и запускаю следующее:

    Set WkBk2 = ActiveWorkbook

    MsgBox (WkBk2.Name)
    WkBk2.Worksheets(1).Select
    WkBk1.Worksheets(1).Select

В последней строке я получаю сообщение об ошибке «Ошибка времени выполнения 1004; выбор метода класса рабочего листа завершился ошибкой».Кто-нибудь может объяснить источник этой проблемы?Я предполагаю, что это как-то связано с использованием ActiveWorkbook для объявления переменных или с ошибочным методом перехода между книгами.

Следует отметить, что открытый файл - это файл .dat, открытый в excel.

В конечном счете, я хочу иметь код, который будет назначать две таблицы с любым именем файла своим соответствующим переменным.Затем я хочу скопировать и вставить данные между двумя рабочими книгами.

Фактический код указан ниже.Проблема заключается в операторе копирования в цикле for.
«Ошибка времени выполнения« 438 », объект не поддерживает это свойство или метод».Ранее я использовал похожий синтаксис и не могу понять, почему он здесь не работает.

Sub Import3()
    ' Imports TSS samples from backlog

    Dim TSS As Workbook, Backlog As Workbook
    Dim Sample As Range, SearchRange As Range
    Dim Count As Long

    Set TSS = ActiveWorkbook

    ChDir ("C:\lwuser6")
    Workbooks.OpenText Filename:="C:\lwuser6\BACKLOG.DAT", Origin:=437, _
           StartRow:=1, DataType:=xlFixedWidth, FieldInfo:=Array(Array(0, 1), Array(7, _
           1), Array(68, 1), Array(78, 1), Array(86, 1), Array(126, 1), Array(150, 1)), _
           TrailingMinusNumbers:=True
        ' for some reason _ has to be in between "Array(7, _1)"
            ' Can't be between list elements of encompassing list "Array"
    Set Backlog = ActiveWorkbook

    Set SearchRange = Backlog.Worksheets("BACKLOG").Range(Cells(1, 1), _
        Cells(Rows.End(xlDown).Row, 1))
    Count = 14

    For Each Sample In SearchRange
        Backlog.Range(Sample(1, 1), Sample(1, 3)).Copy
        TSS.Range("G" & Count).PasteSpecial (xlValues)
        Count = Count + 2
    Next

End Sub

1 Ответ

2 голосов
/ 26 сентября 2019

Я бы настоятельно рекомендовал выполнить ваш код через Проверки Rubberduck (это бесплатно и с открытым исходным кодом; я управляю проектом), поскольку оно объясняет не только конкретную ошибку, о которой вы спрашиваете, но также можетне позволяют вам вступить во множество обычных ловушек для новичков.

Проблема в том, что Backlog является Workbook объектом, а Workbook не имеет Range члена:

Участник не найден

Вызов доступа к элементу сделан для расширенного интерфейса, который Rubberduckне удалось разрешить, или член не найден.Если VBA не может разрешить тип во время выполнения, возникает ошибка 438.[...]

Вам необходим Worksheet для доступа к Range, Workbook не будет работать.

Обратите внимание, что последующие TSS.Range вызов так же незаконен; -)


Возьми это:

Set Backlog = ActiveWorkbook

И избавься от опоры на стороне-эффект открытия рабочей книги путем захвата объекта Workbook, возвращаемого Workbooks.Open:

Set Backlog = Workbooks.OpenText(Filename:="C:\lwuser6\BACKLOG.DAT", Origin:=437, _
       StartRow:=1, DataType:=xlFixedWidth, FieldInfo:=Array(Array(0, 1), Array(7, _
       1), Array(68, 1), Array(78, 1), Array(86, 1), Array(126, 1), Array(150, 1)), _
       TrailingMinusNumbers:=True)

Nevermind, Workbooks.OpenText не возвращает ссылку на объект Workbook.

Затем возьмите это:

 Backlog.Worksheets("BACKLOG")

И перетащите его в локальную переменную:

Dim backlogSheet As Worksheet
Set backlogSheet = Backlog.Worksheets("BACKLOG")

Теперь вы можете использовать еговезде, где вам нужен этот конкретный лист:

With backlogSheet
    Set SearchRange = .Range(.Cells(1, 1), .Cells(.Rows.End(xlDown).Row, 1))
End With

.. и это должно работать, хотя IMO, поставляющий Range объекты в свойство Worksheet.Range, чувствует себя несколько неправильно (и выдает ошибку 1004, если Sampleдиапазон не указан в backlogSheet):

backlogSheet.Range(Sample(1, 1), Sample(1, 3)).Copy

Не уверен, какой конкретный лист в книге TSS вы хотите вставить, но применяется тот же принцип.Тем не менее, вам, вероятно, даже не нужно подключать буфер обмена:

tssSheet.Range("G" & count & ":I" & count).Value = _
    backlogSheet.Range(Sample(1, 1), Sample(1, 3)).Value
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...