Применение кода к активной книге из другой ошибки книги: такой интерфейс не поддерживается - PullRequest
0 голосов
/ 09 февраля 2020

Я хочу, чтобы нижеприведенный код открывал закрытую книгу и копировал значения из диапазона StartRow и EndRow в активную книгу.

Я получаю

ошибка 1004 "Такой интерфейс не поддерживается ".

on line "xlBook.Sheets(ShName).Range(Cells(StartRow, 1), Cells(EndRow, 1)).Select"

Когда я запускаю этот код прямо в книге, из которой я хочу скопировать данные, она работает.

Sub GetDataFromClosedBook()

'copy data from closed workbook to active workbook

Dim xlApp As Application
Dim xlBook As Workbook
Dim sh As Object

Set xlApp = CreateObject("Excel.Application")

'Path source Wokrbook
Set xlBook = xlApp.Workbooks.Open("C:\Users\name\Desktop\EXCEL USEFUL DOSC\Missing Data Check New Process\Missing Data Reports\" & Sheets("Data Check").Range("C3").Value & ".xlsx")

xlApp.Visible = True

ShName = Sheets("Data Check").Range("C3").Value

With xlBook.Sheets(ShName)

    StartRow = .Range("E:E").Find(what:="January-2020", after:=.Range("E1")).Row
    EndRow = .Range("E:E").Find(what:="January-2020", after:=.Range("E1"), searchdirection:=xlPrevious).Row

    'ThisWorkbook.Activate
    xlBook.Sheets(ShName).Range("A2").Value = ShName

    xlBook.Sheets(ShName).Range(Cells(StartRow, 1), Cells(EndRow, 1)).Select

    'Sheets(ShName).Range(Cells(StartRow, 1), Cells(EndRow, 1)).Select
End With

xlApp.DisplayAlerts = False
xlBook.Close
xlApp.Quit

Set xlBook = Nothing
Set xlApp = Nothing
Set xlBook = ActiveWorkbook

Set sh = Sheets("Dealer_ID Check")

sh.Activate
Range("A1").Select
sh.Paste

End Sub

Ответы [ 2 ]

1 голос
/ 10 февраля 2020

Соединив все комментарии, ваш код может быть преобразован в

Option Explicit

Sub GetDataFromClosedBook()
    'copy data from closed workbook to active workbook

    Dim wbData As Workbook
    Dim wbDest As Workbook

    Dim wsDataCheck As Worksheet
    Dim wsDealerIDCheck As Worksheet
    Dim wsReports As Worksheet

    Dim ShName As String
    Dim PthName As String
    Dim FlName As String
    Dim rStartRow As Range, rEndRow As Range
    Dim rng As Range

    Set wbDest = ActiveWorkbook ' not prefered, better to be explicit

    Set wsDataCheck = wbDest.Worksheets("Data Check")

    'Path source Wokrbook
    PthName = "C:\Users\name\Desktop\EXCEL USEFUL DOSC\Missing Data Check New Process\Missing Data Reports\"
    FlName = wsDataCheck.Range("C3").Value
    ShName = wsDataCheck.Range("C3").Value

    On Error Resume Next
        Set wbData = Workbooks.Open(PthName & FlName & ".xlsx")
    On Error GoTo 0
    If wbData Is Nothing Then
        ' File didn't open
        Exit Sub
    End If

    Set wsReports = Nothing
    On Error Resume Next
        Set wsReports = wbData.Worksheets(ShName)
    On Error GoTo 0
    If wsReports Is Nothing Then
        ' No such sheet
        GoTo CleanUp
    End If

    With wsReports
        Set rStartRow = .Range("E:E").Find(What:="January-2020", After:=.Range("E1"), LookIn:=xlValues, LookAt:=xlWhole, SearchDirection:=xlNext)
        Set rEndRow = .Range("E:E").Find(What:="January-2020", After:=.Range("E1"), SearchDirection:=xlPrevious)

        If rStartRow Is Nothing Or rEndRow Is Nothing Then
            ' Search term not found, What Now?
            GoTo CleanUp
        End If

        .Range("A2").Value = ShName

        Set rng = .Range(rStartRow, rEndRow)
' For debug purposes only
.Activate  ' the worksheet
rng.Select ' the range
    End With

    Application.DisplayAlerts = False
    ' do you want to save the change you made to wbData?
    wbData.Close True ' or wbData.Save False

    Set wsDealerIDCheck = wbDest.Worksheets("Dealer_ID Check")

    '  continue ...

Exit Sub
CleanUp:
    If Not wbData Is Nothing Then wbData.Close False
End Sub

0 голосов
/ 10 февраля 2020

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

Комментаторы, мы вежливы и не используем строгие термины, но я не вежлив: ActiveSheet не то, что вы думаете.

То, что вы думаете ActiveSheet во время проектирования, практически никогда не будет равным ActiveSheet во время выполнения. Конечно, бывают случаи, когда они есть, но такие определенности редки, если только вы не приложите усилия, чтобы затем воплотить их в реальность. Все остальное время вы должны явно ссылаться на ваши диапазоны. Считайте, что это жизненно важный навык

Предположим, вы установили указатель на книгу и открываете ее, любой лист, на который она открывается, становится ActiveSheet. Обычно это лист, который последний раз просматривали при сохранении книги, но это ни в коем случае не гарантируется.

Что еще менее гарантировано, так это ваше предположение, что он откроется для листа «Проверка данных».

Вы можете читать и писать на листе «Проверка данных» в течение всего дня, не обращая внимания, является ли он ActiveSheet или нет, но вы можете только Select ячейка на нем, когда это ActiveSheet.

Переменная рабочего листа ShName установлена ​​на рабочий лист «Проверка данных». Ни в коем случае вы не проверяли ShName как ActiveSheet, но ShName должно быть ActiveSheet, чтобы предотвратить ошибку в этой строке:

xlBook.Sheets(ShName).Range(Cells(StartRow, 1), Cells(EndRow, 1)).Select
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...