vb.net автоматизация обновления файлов Excel данными из OLAP-кубов

#excel #vb.net #olap-cube

#excel #vb.net #olap-куб

Вопрос:

Я разрабатываю процедуру exe в VB.NET который обрабатывает несколько файлов Excel (с данными из кубов OLAP) в цикле (обрабатывая все файлы Excel, расположенные в той же папке, где находится exe):

  • открыть файл
  • включить содержимое
  • запись в 2 ячейки
  • вызовите RefreshAll (обновить подключения к данным)
  • сохраните и закройте

Обычно это работает, но с большими файлами Excel (с большим количеством формул CUBEVALUE) Я получил случайные ошибки, вероятно, потому, что Excel не отвечает. Я думаю, что проблема не в вызове RefreshAll, потому что моя процедура не вернула управление и ожидает его завершения, но в некоторых файлах режим вычисления установлен с «Автоматическим», поэтому, как только файл открывается или после обновления, все формулы вычисляются, но (перед этим вычисления выполнены) мои процедуры возвращают управление, и я получаю сообщение об ошибке, когда он пытается отредактировать ячейку или сохранить файл.

Я пытался дождаться, пока состояние вычисления = xlDone, но безуспешно.

После обновления подключений к данным в строке состояния я читаю следующее: ВЫЧИСЛЕНИЕ ПРОЦЕССОРОВ (2) или ВЫПОЛНЕНИЕ ФОНОВОГО ЗАПРОСА

Я также пытался установить режим ручного вычисления, но ячейки с формулами не обновляются.

У вас есть какие-либо предложения?

 Imports Excel = Microsoft.Office.Interop.Excel
Imports Microsoft.Office.Interop
Imports System.IO


Public Class Form1

    Dim rootPath As String = System.Windows.Forms.Application.StartupPath

    Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
    
        Dim di As New IO.DirectoryInfo(rootPath)
        Dim aryFi As IO.FileInfo() = di.GetFiles("*.xls*")
        Dim fi As IO.FileInfo
        Dim filename As String

        For Each fi In aryFi
            filename = fi.Name

            processaFile(filename)

            ' pulizia per non avere istanze di Excel aperte nel task manager
            GC.Collect()
            GC.WaitForPendingFinalizers()
            ' pulizia per non avere istanze di Excel aperte nel task manager
            GC.Collect()
            GC.WaitForPendingFinalizers()
        Next

        Me.Close()

    End Sub


    Private Sub processaFile(filenameX)
        Dim oExcel As Excel.Application
        Dim oBook As Excel.Workbook
        Dim oBooks As Excel.Workbooks
        Dim foglio As Excel.Worksheet
        Dim calculationType As Excel.XlCalculation

        oExcel = CreateObject("Excel.Application")
        oExcel.Visible = True ' ''''''''''''False/True
        oBooks = oExcel.Workbooks

        oExcel.AutomationSecurity = Microsoft.Office.Core.MsoAutomationSecurity.msoAutomationSecurityLow ' abilita le macro

        oBook = oBooks.Open(rootPath amp; "" amp; filenameX, UpdateLinks:=True, [ReadOnly]:=False, IgnoreReadOnlyRecommended:=True)

        oBook.Activate()

        oBook.EnableConnections()

        foglio = oBook.Worksheets("Sheetname")
        foglio.Range("C7").Value = "12"
        foglio.Range("C8").Value = "2020"


        oBook.RefreshAll()
        'oExcel.CalculateFullRebuild()
        'oExcel.Application.CalculateUntilAsyncQueriesDone()


        Do While oExcel.Application.CalculationState.ToString <> "xlDone"
            ' wait
        Loop

        'oBook.Close(SaveChanges:=True)
        oBook.Save()
        oBook.Close()
        oBook = Nothing

        oBooks.Close()
        oBooks = Nothing

        oExcel.Quit()
        oExcel = Nothing
    End Sub


End Class
 

Комментарии:

1. Просто для отладки, вы пытались добавить sleep в некоторых местах?

2. @ChristopherOezbek: спасибо за ответ, я постараюсь добавить некоторые Threading.Thread.Sleep(10000) . Для обновления / вычисления некоторых файлов требуется много времени (в зависимости от производительности компьютера пользователя / подключений к БД / …), и я должен округлить этот интервал времени до часа или более для этих файлов, поэтому, как вы сказали, я могу сделать это только в режиме отладки.