Лист Excel в приложении Windows без открытия приложения Excel - PullRequest
1 голос
/ 18 ноября 2011

Я конвертирую несколько проектов VBA в приложения Windows Form.Единственная проблема, с которой я столкнулся, заключается в том, что некоторые функции Excel необходимы для приложения, например формулы R1C1.Я не хочу создавать экземпляр приложения Excel или получать доступ к сохраненным рабочим листам.Все данные извлекаются путем запроса баз данных Oracle.2-мерные массивы не подходят, потому что столбцы содержат разные типы данных, а DataGridView слишком медленны для работы.

Я думал, что простого затемнения объекта Microsoft.Office.Interop.Excel.Worksheet будет достаточно, нопрограмма продолжала давать сбой, и после проверки элементов объекта в режиме отладки я обнаружил, что каждое значение говорит следующее:

{"Невозможно привести объект COM типа" Microsoft.Office.Interop.Excel.WorksheetClass'to interface type' Microsoft.Office.Interop.Excel._Worksheet '. Эта операция завершилась неудачно, поскольку произошел сбой вызова QueryInterface для COM-компонента для интерфейса с IID' {000208D8-0000-0000-C000-000000000046} 'из-за следующегоошибка: такой интерфейс не поддерживается (Исключение из HRESULT: 0x80004002 (E_NOINTERFACE)). "}

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

Ответы [ 2 ]

1 голос
/ 28 марта 2013

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

    Dim xlApp As New Microsoft.Office.Interop.Excel.Application

    Dim oldCI As System.Globalization.CultureInfo = System.Threading.Thread.CurrentThread.CurrentCulture
    System.Threading.Thread.CurrentThread.CurrentCulture = New System.Globalization.CultureInfo("en-US")
    xlApp.Workbooks.Add()
    xlApp.ActiveSheet.Delete()
    xlApp.ActiveSheet.Delete()

    With xlApp
        With .ActiveSheet.QueryTables.Add("ODBC;DRIVER=SQL Server;SERVER=" & DAO.GetNombreServidor & ";UID=" & DAO.GetLoginUsuario & ";PWD=" & DAO.GetPassUsuario & ";WSID=RICARDO2;DATABASE=" & DAO.GetNombreBaseDeDatos & "", xlApp.Range("A1"))
            .CommandText = "SELECT * FROM ESTADOS"
            .FieldNames = True
            .RowNumbers = False
            .FillAdjacentFormulas = False
            .PreserveFormatting = True
            .RefreshOnFileOpen = False
            .BackgroundQuery = True
            '.RefreshStyle = xlOverwriteCells
            'xlInsertDeleteCells
            .SavePassword = False
            .SaveData = False
            .AdjustColumnWidth = True
            .RefreshPeriod = 0
            .PreserveColumnInfo = False
            .Refresh(False)
        End With
    End With

    System.Threading.Thread.CurrentThread.CurrentCulture = oldCI

    xlApp.Visible = True

Надеюсь, это поможет!

1 голос
/ 18 ноября 2011

Вам, вероятно, нужно правильно обыграть ваш объектДля работы с рабочим листом требуется COM-объект Excel, поэтому обычно сначала выполняется мгновенный запуск его, а затем доступ к листуВот пример кода:

Dim xl As Microsoft.Office.Interop.Excel.Application
xl = New Microsoft.Office.Interop.Excel.Application
Dim wb As Microsoft.Office.Interop.Excel.Workbook
wb = xl.Workbooks.Add()
Dim ws As Microsoft.Office.Interop.Excel.Worksheet
ws = wb.ActiveSheet

Теперь вы можете работать со своим ws.Обратите внимание, что я не запускаю его мгновенно, используя Dim .. as New.

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

/// after your are finished
xl.Quit()
Marshal.ReleaseComObject(xl)

Это особенно важно, если вы используете его в виде цикла.

...