Эффективная передача данных из Excel VBA в веб-сервис - PullRequest
0 голосов
/ 24 сентября 2018

У меня есть большой рабочий лист (~ 250K строк, 22 столбца, ~ 40MB простых данных), который должен передавать его содержимое в интрасеть API.Формат не имеет значения.Проблема в том, что при доступе к данным типа

Const ROWS = 250000
Const COLS = 22

Dim x As Long, y As Long
Dim myRange As Variant
Dim dummyString As String
Dim sb As New cStringBuilder

myRange = Range(Cells(1, 1), Cells(ROWS, COLS)).Value2

For x = 1 To ROWS
    For y = 1 To COLS
        dummyString = myRange(x, y) 'Runtime with only this line: 1.8s
        sb.Append dummyString 'Runtime with this additional line 163s
    Next
Next

я получаю замечательный 2D-массив, но я не могу эффективно собирать данные для экспорта по HTTP.Цикл X / Y над массивом и доступом myRange[x, y] имеет время выполнения> 1 мин.Мне не удалось найти метод массива, который помогает получить взбитое / закодированное содержимое двумерного массива.Мой текущий обходной путь - использование буфера обмена ( обходной путь для утечки памяти при использовании большой строки ), который работает быстро, но является грязным обходным решением в моих глазах И имеет одну серьезную проблему: полученные значения отформатированы, «.Значение », а не« .Value2 », поэтому мне необходимо снова преобразовать данные на сайте сервера перед использованием, например, неформатированные ячейки валюты в числа с плавающей запятой.

Какая еще идея для работы с массивом данных?

1 Ответ

0 голосов
/ 28 сентября 2018

Я думаю, что вы создаете два строковых массива A и B.A может иметь размер 1 to ROWS, B может иметь размер 1 to COLUMNS.Перебирая каждую строку в массиве myRange, заполните каждый элемент в B значением каждого столбца в этой строке.После последнего столбца для этой строки и перед тем, как перейти к следующей строке, объедините массив B и присвойте строку в A.С петлей такого размера, помещайте только необходимые вещи внутри самой петли.В конце вы присоединитесь к A.Возможно, вам придется использовать cstr() при назначении элементов для B.

Matschek (OP) смог написать код, основанный на вышеизложенном, но для чьей-либо пользы сам код может быть чем-то вроде:

Option Explicit

Private Sub concatenateArrayValues()

    Const TOTAL_ROWS As Long = 250000
    Const TOTAL_COLUMNS As Long = 22

    Dim inputValues As Variant
    inputValues = ThisWorkbook.Worksheets("Sheet1").Range("A1").Resize(TOTAL_ROWS, TOTAL_COLUMNS).Value2

    ' These are static string arrays, as OP's use case involved constants.
    Dim outputArray(1 To TOTAL_ROWS) As String ' <- in other words, array A
    Dim interimArray(1 To TOTAL_COLUMNS) As String ' <- in other words, array B

    Dim rowIndex As Long
    Dim columnIndex As Long

    ' We use constants below when specifying the loop's limits instead of Lbound() and Ubound()
    ' as OP's use case involved constants.
    ' If we were using dynamic arrays, we could call Ubound(inputValues,2) once outside of the loop
    ' And assign the result to a Long type variable
    ' To avoid calling Ubound() 250k times within the loop itself.

    For rowIndex = 1 To TOTAL_ROWS
        For columnIndex = 1 To TOTAL_COLUMNS
            interimArray(columnIndex) = inputValues(rowIndex, columnIndex)
        Next columnIndex
        outputArray(rowIndex) = VBA.Strings.Join(interimArray, ",")
    Next rowIndex

    Dim concatenatedOutput As String
    concatenatedOutput = VBA.Strings.Join(outputArray, vbNewLine)

    Debug.Print concatenatedOutput

    ' My current machine isn't particularly great
    ' but the code above ran and concatenated values in range A1:V250000
    ' (with each cell containing a random 3-character string) in under 4 seconds.

End Sub
...