Что нового

[Автоматизация] Медленно работает скрипт при переходе на новую версию

Andrey_A

Продвинутый
Сообщения
319
Репутация
68
Работал на версии 3.3.6.1, перешёл на новую версию 3.3.8.0
При новой версии скрипт работает очень долго. Только что тестировал на старой версии работает минуту, на новой 5 минут.

Подскажите почему и что можно сделать?

Код:
; CopyXlsInText.au3
; ================   Описание   ===================================
; Копирование из файлов XLS, XLSX строк, столбцов в текстовый файл
; ================  Параметры ===================================
; В командной строке  должно быть прописано 7 - 11 параметров:
; - - - - - - - - - - - - - - - - - Обязательные - - - - - - - - - - - - - - - - - - - -
; 1) Номер листа с какого считывать информацию
; 2) С какой строки начать считывание
; 3) С какого столбца начать считывание
; 4) К-во считываемых рядов (строк) (0 - все)
; 5) К-во считываемых колонок (столбцов)
; 6) Путь\к\файлу.xls
; 7) Путь\к\сохранению\файла.txt
 ; (можно вводить пути с переменными окружения)
; - - - - - - - - - - - - - - - Дополнительные  - - - - - - - - - - - - - - - - - - - -
; 8) 1 = Удалять пустые строки   0 = оставить как есть
; 9) строка-вставка между колонками
; 10)  строка-вставка в начале строки
; 11)  строка-вставка в конце строки
; ================    Примеры    ===================================
; 1 2 0 4 "%%COMMANDER_PATH%%\Files\Lists\CreateMenu\WcmMenuImage.xlsx" "%%COMMANDER_PATH%%\Text.ini"
; 1 2 0 4 "%%COMMANDER_PATH%%\Files\Lists\CreateMenu\WcmMenuImage.xlsx" "%%COMMANDER_PATH%%\Text.ini" 1 "___" "| " " |"
; 1 1 1 0 0 %P%N "%T%O.txt" 1 "   " -  Копирование первого листа из xls под курсором в текстовый файл в соседнюю панель
;
; Автор:             Аверин Андрей
; Версия:          1.0 (12.10.2010)
; Mail:                 [email protected]
; Site:                  http://tc-image.3dn.ru/forum/3-83-329-16-1330565367
; ===============================================================
#include <Excel.au3>

If $CmdLine[0] < 7  Then
  MsgBox(16 + 262144, "Запись из табличного файла строк и столбцов в файл", _
  "Не хватает параметров!" & @CRLF & "Должно быть минимум СЕМЬ, а у вас" & _
  $CmdLine[0] & @CRLF & "Пропишите и повторите попытку!" & @CRLF & _
  "Подробную информацию читайте в коментариях скрипта", 10)
  Exit
Endif

$List = Number($CmdLine[1])
$StartRow = Number($CmdLine[2])
$StartCol = Number($CmdLine[3])
$RowCnt = Number($CmdLine[4])
$ColCnt = Number($CmdLine[5])
$XlsFile = _TCHExpandEnv($CmdLine[6])
$TxtFile = _TCHExpandEnv($CmdLine[7])

$Text = ""
$Insert = ""
$Control = ""
$Contr = 0
$InsertRight = ""
$InsertLeft = ""
if $CmdLine[0] > 7 Then $Contr = $CmdLine[8]
if $CmdLine[0] > 8 Then $Insert = $CmdLine[9]
if $CmdLine[0] > 9 Then $InsertRight = $CmdLine[10]
if $CmdLine[0] > 10 Then $InsertLeft = $CmdLine[11]

; Открываем xls , считываем нужные строки, колонки и закрываем
$oInFile = _ExcelBookOpen($XlsFile, 0, True)
; номер листа
$oInFile.Sheets($List).Select()

$aData = _ExcelReadSheetToArray($oInFile, $StartRow, $StartCol, $RowCnt , $ColCnt)
_ExcelBookClose($oInFile, 0)

if $RowCnt = 0 Then $RowCnt = UBound($aData,1) - 1 ;размерность массива (к-во строк)
if $ColCnt = 0 Then $ColCnt = UBound($aData,2) - 1 ;размерность массива (к-во колонок)

; Открываем выходной файл для записи - с очисткой
$hFile = FileOpen($TxtFile, 2)

; Записываем  данные
For $i=1 To $RowCnt
    For $j=1 To $ColCnt
       if $aData[$i][$j] = "" Then $aData[$i][$j] = ""
       $Text = $Text & StringFormat("%s", $aData[$i][$j]) & $Insert
       $Control = $Control & $Insert
    Next
    ; проверка на пустые строки
    if $Contr = 1 And StringCompare($Control, $Text,2) = 0 Then
    Else
       FileWriteLine($hFile, $InsertLeft & $Text & $InsertRight)
    Endif
    $Text = ""
    $Control = ""
Next

; функция разворачивания переменных окружения
Func _TCHExpandEnv($sText)
    $aResult = StringRegExp($sText, "%(\w+)%", 3)
    If IsArray($aResult) Then
        For $i = 0 To UBound($aResult)-1
            $sText = StringReplace($sText, "%" & $aResult[$i] & "%", EnvGet($aResult[$i]))
        Next
    EndIf
    Return $sText
EndFunc
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Предупреждение За нарушение правил форума (пункт В.11):
Любые отрывки AutoIt кода необходимо заключать в тег [autoit]
autoit.gif
(подробнее), а обычный код соответственно в тег [code]
code.gif
(подробнее). Также большие выдержки текста помещайте под тег [spoiler]
spoiler.gif
(подробнее), там где это поддерживается естественно. Как в случае с названием темы, также короткое и эргономичное сообщение привлекает больше внимания, и шансы на получение конкретного ответа увеличиваются.


С уважением, ваш Глобальный модератор.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Новая, это 3.3.8.1.
 

asdf8

Скриптер
Сообщения
564
Репутация
152
Yashied [?]

Так, по сравнению с 3.3.8.0, вся разница - исправлены ошибки в Скайте, остальное - все одинаковое.


Andrey_A [?]
что можно сделать?

Можно _ExcelReadSheetToArray заменить на _ExcelReadSheetToArrayFast с оффорума.

Т.е. заменить строку:
Код:
$aData = _ExcelReadSheetToArray($oInFile, $StartRow, $StartCol, $RowCnt, $ColCnt)


на:
Код:
$aData = _ExcelReadSheetToArrayFast($oInFile, $StartRow, $StartCol, $RowCnt, $ColCnt)

Func _ExcelReadSheetToArrayFast($oExcel, $firstRow = 1, $firstCol = 1, $lastRow = 0, $lastCol = 0, $vSheet = "")
	$usedRange = _ExcelSheetUsedRangeGet($oExcel, $vSheet)
	If IsArray($usedRange) Then
		If $lastCol = 0 Then $lastCol = $usedRange[2]
		If $lastRow = 0 Then $lastRow = $usedRange[3]
	Else
		Return 0
	EndIf
	
	Dim $aFixedArray[$lastRow - $firstRow + 2][$lastCol - $firstCol + 2]
	ProgressOn(" Progress", " Reading Excel Sheet...")
	
	For $i = $firstRow To $lastRow
		ProgressSet($i / ($lastRow / 100), "Running " & $i & " of " & $lastRow - $firstRow)
		$aTempArray = $oExcel.Activesheet.Range($oExcel.Cells($i, $firstCol), $oExcel.Cells($i, $lastCol)).Value
		$b = $i - $firstRow + 1
		For $a = 0 To ($lastCol - $firstCol)
			$c = $a + 1
			$aFixedArray[$b][$c] = $aTempArray[$a][0]
		Next
	Next
	
	ProgressOff()
	Return $aFixedArray
EndFunc ;==>_ExcelReadSheetToArrayFast

;===============================================================================
;
; Description:      Return the last cell of the used range in the specified worksheet.
; Syntax:           $array = _ExcelSheetUsedRangeGet($oExcel, $vSheet)
; Parameter(s):     $oExcel - An Excel object opened by a preceding call to _ExcelBookOpen() or _ExcelBookNew()
;                   $vSheet - The sheet name or number to be checked.
; Requirement(s):   None
; Return Value(s):  On Success - Returns an array of used range values:
;                       $array[0] - The last cell used, in A1 format (if 0 is returned, worksheet is blank)
;                       $array[1] - The last cell used, in R1C1 format
;                       $array[2] - The last column used, as an integer
;                       $array[3] - The last row used, as an integer
;                   On Failure - Returns 0 (as non-array numeric value) and sets @error on errors:
;                       @error=1 - Specified object does not exist
;                       @error=2 - Invalid sheet number
;                       @error=3 - Invalid sheet name
; Author(s):        DaLiMan, MRDev, SEO <locodarwin at yahoo dot com>
; Note(s):          Upon return, $array[0] will equal numeric value 0 if the worksheet is blank
;
;===============================================================================

Func _ExcelSheetUsedRangeGet($oExcel, $vSheet = "")
	Local $aSendBack[4], $sTemp, $aSheetList, $fFound = 0
	If Not IsObj($oExcel) Then Return SetError(1, 0, 0)
	If Not $vSheet = "" Then
		If IsNumber($vSheet) Then
			If $oExcel.Sheets.Count < $vSheet Then Return SetError(2, 0, 0)
		Else
			$aSheetList = _ExcelSheetList($oExcel)
			For $xx = 1 To $aSheetList[0]
				If $aSheetList[$xx] = $vSheet Then $fFound = 1
			Next
			If Not $fFound Then Return SetError(3, 0, 0)
		EndIf
		$oExcel.Sheets($vSheet).Select
	Else
		$oExcel.Activesheet.Select
	EndIf
	
	$aSendBack[0] = $oExcel.Application.Selection.SpecialCells($xlCellTypeLastCell).Address
	$aSendBack[1] = $oExcel.Application.Selection.SpecialCells($xlCellTypeLastCell).Address(True, True, $xlR1C1)
	$aSendBack[0] = StringReplace($aSendBack[0], "$", "")
	$sTemp = StringRegExp($aSendBack[1], "[RZ]([^CS]*)[CS](.*)", 3)
	$aSendBack[2] = Number($sTemp[1])
	$aSendBack[3] = Number($sTemp[0])
	If $aSendBack[0] = "A1" And $oExcel.Activesheet.Range($aSendBack[0]).Value = "" Then $aSendBack[0] = 0
	Return $aSendBack
EndFunc ;==>_ExcelSheetUsedRangeGet
 
Автор
A

Andrey_A

Продвинутый
Сообщения
319
Репутация
68
При замене на _ExcelReadSheetToArrayFast - процесс ещё дольше - выскакивает прогресс бар - и начинает читать - у меня XLS более 30000 строк. И вот он всё это пересчитывает...
 

asdf8

Скриптер
Сообщения
564
Репутация
152
Andrey_A [?]
При замене на _ExcelReadSheetToArrayFast - процесс ещё дольше - выскакивает прогресс бар

Прогресс бар отнимает максимум пару процентов времени обработки и его можно легко отключить, а насчет того, что процесс еще дольше, то у меня, например, наоборот - _ExcelReadSheetToArrayFast раз в 10 быстрее работает, чем _ExcelReadSheetToArray.
 
Верх