Xlapp.quit() Не Срабатывает После Errh

Тема в разделе "Lotus - Программирование", создана пользователем Eugen, 24 янв 2014.

  1. Eugen

    Eugen Well-Known Member

    Регистрация:
    22 мар 2012
    Сообщения:
    172
    Симпатии:
    0
    Всем здрасьте.

    Есть некий агент, формирующий отчет в xls. В случае ошибки хочу глушить процесс. Делаю так:
    Код (LotusScript):
    Sub Initialize
    On Error GoTo errH

    Dim xlApp, xlWorkbook, xlSheet
    Dim curDoc as NotesDocument

    Set xlApp = CreateObject({Excel.Application})
    xlApp.SheetsInNewWorkbook = 1
    Call xlApp.Workbooks.Add({})
    Set xlWorkbook = xlApp.Workbooks(1)
    Set xlSheet = xlWorkbook.Worksheets(1)

    'тут будет заполнение отчета
    xlWorkbook.Sheets(1).Name = {ТТ №} & curDoc.fldLRPNumber(0)

    endSub:
    Exit sub
    errH:
    Print {Error "} & Error$ & {" in line } & Erl
    If IsObject(xlApp) Then
    Call xlApp.Quit()
    End If
    Resume endSub
    End Sub
    В этом случае curDoc не определен, вывалится ошибка и процесс должен убиться, но этого почему то не происходит, а если делаю так, то все ок:
    Код (LotusScript):
    Sub Initialize
    On Error GoTo errH

    Set xlApp = CreateObject({Excel.Application})
    xlApp.SheetsInNewWorkbook = 1
    Call xlApp.Workbooks.Add({})
    Set xlWorkbook = xlApp.Workbooks(1)
    Set xlSheet = xlWorkbook.Worksheets(1)

    Call xlApp.Quit()

    endSub:
    Exit sub
    errH:
    Print {Error "} & Error$ & {" in line } & Erl
    If IsObject(xlApp) Then
    Call xlApp.Quit()
    End If
    Resume endSub
    End Sub
    Т.е. если делать Call xlApp.Quit() не в обработчике ошибок, то нужный процесс убивается без проблем. Причем вот что странно - у меня стоит 2007 офис и есть глюки, у коллеги стоит 2010-й и у него все ок, т.е. процесс убивается вне зависимости от того, где размещается Call xlApp.Quit().

    ЗЫ: Где то в соседней теме встречал такую фишку:
    Код (LotusScript):
    Sub CloseMSobj(execName As String)
    On Error GoTo ErrH
    Dim objs As Variant
    Dim strSQL As String
    Dim strWMI As String
    strWMI = "winmgmts:"
    strSQL = "Select * From Win32_Process "
    strSQL = strSQL & {where Name = '} & execName &{'}
    Set objs = GetObject(strWMI).ExecQuery(strSQL)
    If Not objs Is Nothing Then
    ForAll obj In objs
    obj.Terminate
    End ForAll
    End If
    Quit:
    Exit Sub
    ErrH:
    Resume Quit
    End Sub
    , но мне это не подходит, т.к. она глушит вообще все процессы эхеля.
     
  2. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    У нас так, пока глюков не было.
    На рабочей машине MS_2010, у большинства пользователей тоже.
    На части серверов 2003-2007.
    DisplayAlerts не дает предупреждений о "Сохранить", может кстати из-за него и не закрывается.
    Код (LotusScript):
    GoTo endh
    handler:
    If Not wapp Is Nothing Then
    wapp.DisplayAlerts = False
    Call wapp.Quit()
    Set wapp = nothing
    End If
    Resume endh
    endh:
     
  3. Eugen

    Eugen Well-Known Member

    Регистрация:
    22 мар 2012
    Сообщения:
    172
    Симпатии:
    0
    не помогло(
     
  4. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    Бредово звучит, но похоже косяк в версии. Про 2007 везде пишут, что пока не сохранишь закрыть не дает.
    Обходят через
    Код (LotusScript):
    ThisWorkbook.Saved = True
    затем Quit
    Типа ставят флаг для Application.ActiveWorkbook.Saved = True что она сохранена.
     
  5. Eugen

    Eugen Well-Known Member

    Регистрация:
    22 мар 2012
    Сообщения:
    172
    Симпатии:
    0
    И снова не помогло. В дебагере наблюдается вот такая картина:
    Снимок.PNG
    Шаг "Set xlApp = Nothing" уже прошел, а переменная xlApp еще не очистилась. Из-за чего такое может быть?
     
  6. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    Хм,первый раз такое встречаю...
    и условие isObject прошел и команды сделал...
    Может сделать двойной обработчик ошибок? может в Excel при закрытии что падает, а логов нет.
    Можно попробовать обновить версию, либо SP какой поставить к офису. Пользователи на каком сидят?

    Тогда может объект попробовать не создавать, а через GetObject получить?
     
  7. Eugen

    Eugen Well-Known Member

    Регистрация:
    22 мар 2012
    Сообщения:
    172
    Симпатии:
    0
    На самом разном, от 2003-го до 2010-го. Щас попробую какой-нибудь сервис пак найти...

    Добавлено:
    это как?
     
  8. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.073
    Симпатии:
    299
    а потом сервиспак для винды...
    готов поспорить - что будете биться с траблой долго и возможно - переписать без эхеля займет меньше времени ;)
    а потом проапдейтят эхель - опять что-то сломается... и по новой
     
  9. garrick

    garrick Lotus team
    Lotus team

    Регистрация:
    26 окт 2009
    Сообщения:
    770
    Симпатии:
    50
    Мне кажется некорректно без спроса пользователя закрывать Excel. А вдруг он в нём какую-то работу делает, помимо вашего отчёта, уже много написал и не сохранил?
    1. Получайте объект Excel через GetObject - если Excel уже запущен, вы его получите, если нет получите ошибку в обработчике которой выполните CreateObject. Это убережет вас от запуска множества копий Excel, а так же может реанимировать зависшие ранее (иногда они оживают ;)).
    2. Если вы сделали как написано в п.1 теперь вы точно знаете можете ли вы закрыть Excel, т.к. открыли его сами или нет, т.к. пользователь что-то делал в нём до вас.
    3. Если закрывать Excel не надо, но вы хотите "скрыть" результаты формирования вашего отчёта, закройте созданный вами Workbook.
     
  10. Eugen

    Eugen Well-Known Member

    Регистрация:
    22 мар 2012
    Сообщения:
    172
    Симпатии:
    0
    Там же вроде на каждый документ свой отдельный процесс. Поэтому я и хотел сделать через .Quit - он убивает только собственный процесс.
     
  11. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    Eugen
    Это-то да, но может решим еще проблему почему вылетает с ошибкой?
    По идее же ее быть не должно.
     
  12. garrick

    garrick Lotus team
    Lotus team

    Регистрация:
    26 окт 2009
    Сообщения:
    770
    Симпатии:
    50
    Раньше были прецеденты - в каких-то версия весь Excel закрывался сразу, больше с тех пор так никогда не делаю. Как там сейчас с 2007-2010 не знаю, может что-то пофиксили. Но опять же как оно будет дальше, в следующих версиях, тоже неизвестно.
     
  13. Eugen

    Eugen Well-Known Member

    Регистрация:
    22 мар 2012
    Сообщения:
    172
    Симпатии:
    0
    В общем ересь какая-то... оставил в таком виде:
    Код (LotusScript):
    xlWorkBook.Saved = True
    Call xlApp.Quit()
    Set xlApp = Nothing
    Вроде работает, пользователи не жалуются. Самый "прикол" в том, что и у меня заработало, хотя сервис пак так и не поставил... Чертовщина какая-то. :angry2:
    ЗЫ: Если не сложно, дайте ссыль, где почитать про MS Office API.
     
  14. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    MS 2013
    MS 2010
    ссылки на Excel, но там переходы есть.
     
  15. Eugen

    Eugen Well-Known Member

    Регистрация:
    22 мар 2012
    Сообщения:
    172
    Симпатии:
    0
    Спасибо, изучу на досуге.
     
  16. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.073
    Симпатии:
    299
    я так понимаю - неделя потрачена на эксперименты :angry2:
    лучше теперь потратить время на изучение POI и JXLS кучу времени сбережете...
    я понимаю лет 10-ть назад - эти инструменты либо отсут. либо были в зачаточном состоянии, но сейчас-то...
     
  17. Eugen

    Eugen Well-Known Member

    Регистрация:
    22 мар 2012
    Сообщения:
    172
    Симпатии:
    0
    Про POI слышал много хороших вещей и в планах стоит изучение, но в большинстве старых баз используются OLE-объекты, так что их тоже было бы неплохо знать.
     
  18. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.073
    Симпатии:
    299
    сделайте адаптер или рапер (шаблон программирования) и легко замените вызов Вин объекта на ваш...
    я таким образом, в рамках проекта, менял вывод в Excel, на вывод в CSV (разные шиты - разные файлы, т.к. вркбук был многошитовый)
     
  19. Eugen

    Eugen Well-Known Member

    Регистрация:
    22 мар 2012
    Сообщения:
    172
    Симпатии:
    0
    Попробую, спасибо за совет.
     
  20. NickProstoNick

    NickProstoNick Статус как статус :)

    Регистрация:
    22 авг 2008
    Сообщения:
    1.766
    Симпатии:
    39
    1. почему в обработчике просто не написать xlApp.Quit() ?
    2. почему не перебдеть возможные ошибки?
    • контролировать наличие документа
    • не писать так curDoc.fldLRPNumber(0). Лучше curDoc.GetItevNalue( "fldLRPNumber" )(0). Тогда если поля нет - вернется пустая строка. Контролировать передачу дат в эксель
     

Поделиться этой страницей