Что нового

Обработка Excel2007 не сохраненного листа >65535 строк с максимальной скоростью

Автор
V

ViktorSPB

Новичок
Сообщения
109
Репутация
0
Re: Обработка Excel2007 не сохраненного листа с максимальной скоростью

madmasles, спасибо! Локальную задачу это решит, но я набрел еще на один нюанс.
Большой файл не обрабатывается.
прочитал на форумах следующее:
Application.WorksheetFunction.Transpose не может выдать массив более 65536 и обрежет все записи, длина строки которых более 255 символов. Обрежет их до 255. А если не применять Transpose, то можно вывести либо только по столбцам, либо делать доп. цикл для «переворачивания» массива. Что «убъёт» выигрыш по скорости.
В общем, ставлю больший файл и метод ругается.
Удалял частично из файла данные, метод то работал то нет.. не стабильно. В общем... Вариант отличный для общего развития и для анализа меньших таблиц очень пригодится, но для моей задачи, думаю нет. Снова поправил тему, внес доп. условие.

Похоже, что часть методов не переписались под 2007 и благополучно пришли из 2003 Excel со своими ограничениями.. Чувствую, надо эту тему бросать и копать DDE сервер, принимать данные напрямую. Поправил коды DDE библиотек, но там тоже ошибки вываливаются, переменные не продекларированы.. Какой-то тупик ... :wacko:


Добавлено:
Сообщение автоматически объединено:

Нашел тему на форуме, где пытались поговорить о DDE сервере.
[box title=TitleBox]http://autoit-script.ru/index.php/topic,1998.15.html[/box]
Если есть кому что ответить на неё, ответьте, пожалуйста, а то тут оффтоп уже может получиться.
 
Автор
V

ViktorSPB

Новичок
Сообщения
109
Репутация
0
Уважаемый, Dreadfulangel.
Ваш способ обработки листа Excel - просто супер!
Еще раз спасибо, научили.

Я столкнулся с некоторыми сложностями при обработке большого листа и потому слегка дописал Вашу функцию.
Добавив эти строки ниже проверок на ошибки в начале функции, не получаем ошибок при запросе лишних данных.
Код:
Local $iTrueRowsCount = $oExcel.Activesheet.UsedRange.Rows.Count
Local $iDefRows = $iStartRow + $iRowCnt
If $iTrueRowsCount < $iStartRow Then Return $avRET
If $iTrueRowsCount < $iDefRows Then $iRowCnt = $iTrueRowsCount - $iStartRow + 1

А именно. Если пользователь запросит данные начиная со строки большей чем есть всего на листе, либо попросит у пустого листа строки, на выходе он получит массив [0,0].
Если же запросит начиная со строки имеющей место на листе, но верхний диапазон уйдет за пределы данных на листе, эта верхняя граница автоматически обрежется до последней строки.
Таким образом, функция, по-моему, становится не убиваемой. Надеюсь, кому-нибудь еще пригодится, чтоб хоть какая то польза и от меня была на форуме :smile:
 

F9

Новичок
Сообщения
71
Репутация
2
Порция некропостинга ;D

Всем привет, кто работал в данной теме!
Интересует работа функции _ExcelReadSheetToArrayQuick :
по умолчанию функция возвращает массив, Col[0] у которого пусто.
Как изменить запись в массив, чтобы в Col[0] писался номер строки Row. Именно значение ?

Дело в том, что у меня достаточно большой файл Excel, порядка 20 000 строк. Хотелось бы по текущему заполнению массива (отслеживать например _MaxIndex по 1 колонке, чтобы понять процент заполнения массива и выдать примерное время ожидания.
На всякий случай вся функция:
Код:
#include <Excel.au3>
#include <Array.au3>
Local $oExcel = _ExcelBookOpen(@ScriptDir & "\Reestr.xlsx",0) ;Create new book, make it visible

; We can fill-up some cells using a simple loop and random Numbers
;~ For $y = 1 To 100 ;Start on Column 1
;~     For $x = 1 To 100
;~         _ExcelWriteCell($oExcel, Round(Random(1000, 10000), 0), $x, $y) ;Some random numbers to file
;~     Next
;~ Next

local $iTimer=TimerInit()
$aArray = _ExcelReadSheetToArray($oExcel) ;Using Default Parameters
ConsoleWrite("_ExcelReadSheetToArray: "&Timerdiff($iTimer) & @LF)
_ArrayDisplay($aArray, "Array using Default Parameters")

Func _ExcelReadSheetToArrayQuick($oExcel, $iStartRow = 1, $iStartColumn = 1, $iRowCnt = 0, $iColCnt = 0)
    Local $avRET[1][2] = [[0, 0]] ; 2D return array
    ; Test inputs
    If Not IsObj($oExcel) Then Return SetError(1, 0, 0)
    If $iStartRow < 1 Then Return SetError(2, 0, 0)
    If $iStartColumn < 1 Then Return SetError(2, 1, 0)
    If $iRowCnt < 0 Then Return SetError(3, 0, 0)
    If $iColCnt < 0 Then Return SetError(3, 1, 0)

    ; Get size of current sheet as R1C1 string
    ;     Note: $xlCellTypeLastCell and $x1R1C1 are constants declared in ExcelCOM_UDF.au3
    Local $sLastCell = $oExcel.Application.Selection.SpecialCells($xlCellTypeLastCell).Address(True, True, $xlR1C1)

    ; Extract integer last row and col
;~     $sLastCell = StringRegExp($sLastCell, "\A[^0-9]*(\d+)[^0-9]*(\d+)\Z", 3)
    Local $iLastRow = $sLastCell[0]
    Local $iLastColumn = $sLastCell[1]

    ; Return 0's if the sheet is blank
    If $sLastCell = "R1C1" And $oExcel.Activesheet.Cells($iLastRow, $iLastColumn).Value = "" Then Return $avRET

    ; Check input range is in bounds
    If $iStartRow > $iLastRow Then Return SetError(2, 0, 0)
    If $iStartColumn > $iLastColumn Then Return SetError(2, 1, 0)
    If $iStartRow + $iRowCnt - 1 > $iLastRow Then Return SetError(3, 0, 0)
    If $iStartColumn + $iColCnt - 1 > $iLastColumn Then Return SetError(3, 1, 0)

    ; Check for defaulted counts
    If $iRowCnt = 0 Then $iRowCnt = $iLastRow - $iStartRow + 1
    If $iColCnt = 0 Then $iColCnt = $iLastColumn - $iStartColumn + 1

    ; Size the return array
    ReDim $avRET[$iRowCnt][$iColCnt]
    ;$avRET[0][0] = $iRowCnt
    ;$avRET[0][1] = $iColCnt
    $avRET = $oExcel.Application.WorksheetFunction.Transpose($oExcel.Activesheet.Cells($iStartRow, $iStartColumn).Resize($iRowCnt, $iColCnt).Value) ; здесь происходит считывание целым массивом, а не по элементно
    ;Return data
    Return $avRET
EndFunc   ;==>_ExcelReadSheetFromArrayQuick
 

Вложения

  • row.jpg
    row.jpg
    37 КБ · Просмотры: 13

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Код:
Ubound($aArray)
 

F9

Новичок
Сообщения
71
Репутация
2
Массив сначала создается пустым, а затем заполняется данными, Ubound будет всегда возвращать одно число строк.
Вот если бы делить Ubound на _MaxIndex - можно было бы увидеть процент заполнения массива.
Парюсь с заполнением массива :
Код:
$avRET = $oExcel.Application.WorksheetFunction.Transpose($oExcel.Activesheet.Cells($iStartRow, $iStartColumn).Resize($iRowCnt, $iColCnt).Value)

Не пойму, как это работает
 
Верх