Ошибка при импорте в Excel - PullRequest
1 голос
/ 19 февраля 2011

Я пытаюсь импортировать около 1500 файлов Excel в мою систему.Код работает в цикле, и я могу открыть и импортировать около 600 файлов Excel.После этого я получаю сообщение об ошибке типа: Ошибка вызова функции внешнего объекта, открытой в строке 55 .....

Я действительно застрял с этой проблемой, если кто-то может помочь, будет благодарен.1004 *

Код в комментариях:

For ll_LoopCnt = 1 To Dw_1.rowcount( )
    Ls_File_Name = Dw_1.getitemstring( ll_LoopCnt, "file_name")
    Ls_Path =Dw_1.getitemstring( ll_LoopCnt, "file_path")
    ll_Sr_No= Dw_1.getitemNumber( ll_LoopCnt, "sr_no")
    ldt_File_Date= Dw_1.getitemDateTime( ll_LoopCnt, "file_date")
    Excel.Application.DisplayAlerts = "False"
    Excel.WorkBooks.Open( Ls_Path )
    Excel.Application.Visible = False
    Excel.windowstate = 2 // 1 : Normal, 2 : Minimize, 3 : Maximize
    Excel.Application.CutCopyMode = False
    Lb_sheet_rtn = excel.worksheets(7).Activate
    Ls_ClipBoard = clipboard()
    Excel.Application.ActiveWorkbook.Save()
    Excel.Worksheets(7).UsedRange.Copy
    ll_cnt = ds_1.importclipboard()
    IF ll_cnt <= 1 THEN
        Messagebox("Error", "Could not find.")
    Else
        Dw_1.Scrolltorow( ll_LoopCnt )
        Dw_1.SetItem( ll_LoopCnt, "status", 'Success')
        For ll_Inner_LoopCnt = 1 To Ds_1.RowCount( )
            Ds_1.Object.file_path[ll_Inner_LoopCnt] = Ls_Path
            Ds_1.Object.file_name[ll_Inner_LoopCnt] = Ls_File_Name
            Ds_1.Object.file_sr_no[ll_Inner_LoopCnt] = ll_Sr_No
            Ds_1.Object.file_date[ll_Inner_LoopCnt] = ldt_File_Date
        Next
    END IF
    Clipboard(ls_ClipBoard)
    Ds_1.Reset( ) //Reset the data store
    Excel.Application.ActiveWorkbook.Save()
    Excel.Application.ActiveWorkbook.Close(False);
    Excel.Application.Quit
    Excel.Application.CutCopyMode = False
    IF ll_LoopCnt = ll_Excel_Cnt Then //--->> After 100 files reset the memmory
        ll_Excel_Cnt = ll_LoopCnt + 100
        Excel.DisConnectObject()
        DESTROY excel
        DESTROY TEst_Excel
        GarbageCollect ( )
        Excel = Create OLEObject
        Test_Excel = Create OLEObject
        Li_rtn = excel.ConnectToNewObject("excel.application")
        IF li_rtn <> 0 THEN
            MessageBox('Excel error','can not run Excel Program')
            DESTROY Excel
            RETURN 0
        END IF
    End IF
Next
Excel.displayalerts = False
Excel.Application.Quit
Excel.displayalerts = True
Excel.DisConnectObject()
DESTROY Excel
DESTROY Test_Excel /* This is the code i written i dont think the OLE is crashing i think the connnectto the OLE is getting lost after some time, but stile its going fine for almost 600 records.. */

Ответы [ 2 ]

1 голос
/ 21 февраля 2011

Может помочь просмотр строки кода, но обычно это сообщение об ошибке (в контексте OLE, которое, как я предполагаю, имеет место здесь) приходит от PowerBuilder, который выполняет вызов OLE, который хост OLE отклоняет.Исходя из предоставленной вами информации, невозможно определить, произошел ли сбой в работе хоста OLE и он больше не отвечает, или вы перевели хост OLE в состояние, когда эти функции больше не применимы, или объект OLEстал недействительным, или что.

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


Новый февраль21

Я бы также изменил набор обрабатываемых файлов, чтобы я мог определить, является ли ключ к сбою определенным файлом или количество обработанных файлов.Например, если вы избавляетесь от первых 100 файлов, происходит ли сбой в 600-м файле (то же количество) или в 500-м файле (тот же файл)?

Одна из возможностей заключается в том, что у вас заканчиваетсяобъем памяти.Каждая «точка» в ссылке OLE (доступ к атрибуту, вызов метода) создает объект в памяти, который не уничтожается до тех пор, пока не будет собран мусор.Выложенный вами фрагмент кода никогда не войдет в блок, где вызывается GarbageCollect () (ll_Excel_Cnt никогда не инициализируется), поэтому вы можете убедиться, что эта часть работает.Я также избавился бы от ненужных звонков.Например, у вас есть несколько вызовов, которые поддерживают состояние Excel в цикле (например, Excel.Application.Visible), когда их нужно вызывать только один раз.Мне также не ясно из фрагмента кода, зачем вам нужно вызывать Save () в любое время;это может быть и расходным.Эта очистка также должна заставить ваш код работать быстрее.


Удачи,

Терри

0 голосов
/ 22 февраля 2011

Вокруг строки 30 у вас есть

Excel.Application.ActiveWorkbook.Save()
Excel.Application.ActiveWorkbook.Close(False);
Excel.Application.Quit

Вы не должны звонить туда Excel.Application.Quit. Кроме того, я всегда рекомендую помещать все, что использует OLE, в блок Try..Catch и перехватывать OleRuntimeError и RuntimeError.

...