Автор Тема: [Данные, строки] Функция для конвертации списка из ListView в текстовую таблицу  (Прочитано 1505 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн erlik [?]

  • Продвинутый
  • ***
  • Сообщений: 317
  • Репутация: 83
    • Награды
  • Версия AutoIt: 3.3.8.1
Аналогичная функция от guinness, к сожалению, никуда не годится (в отличие от его _GUICtrlListView_SaveHTML), поэтому решил полностью переписать свой прежний вариант (который использовал в DllViewer) и сделать его универcальным, а не только под задачи моей программы. Может, кому то пригодится, как мне пригодилась _SaveHTML от guinness.

Код: AutoIt [Выделить]
#include <GuiListView.au3>

; #FUNCTION# =========================================================================================================
; Name...........: _SaveListAsTxt()
; Description ...: Saves the contents of the list ListView as a text table with formatting
; Syntax.........: _SaveListAsTxt($hListView [, $aArrayMax [, $sHorSepHeader [, $sColumnSep [, $sRowSep [, $sAddingStr [,$CountSpace]]]]]])
; Parameters ....: $hListView     - Handle or identifier the ListView.
;                  $aArrayMax     - [Optional] Аn array of maximum lengths of rows in each column. [Default = -1]
;                  $sHorSepHeader - [Optional] Symbol for horizontal divider title.                [Default = '=']
;                  $sColumnSep    - [Optional] Delimiter character for the header rows of columns. [Default = '|']
;                  $sRowSep       - [Optional] Delimiter character for the rows of columns         [Default = '|']
;                  $sAddingStr    - [Optional] Аppend the number of rows and the timestamp or not. [Default = 1]
;                  $CountSpace    - [Optional] Number of spaces between lines.                     [Default = 1]
; Return values .: Success - Formatted text.
;                  Failure - Empty string.
; Author ........: Erlik (aka Garry Galler)
; Modified.......:
; Remarks........: With an array of predefined values of maximum lengths of rows in each column
;                  function works almost twice as fast.
; Example........: None
;=====================================================================================================================
Func _SaveListAsTxt($hListView, $aArrayMax =-1, $sHorSepHeader = '=', $sColumnSep = '|', $sRowSep = '|', $sAddingStr = 1, $CountSpace = 1)
    ;Local $hTimer = TimerInit()
    Local $iLV_ItemCount,$iLV_ColumnCount,$aLV_TextColumn, $aLV_TextRows, $sHeader='',$sFormatText,$iWidthHeader=0, $sLine='',$iLenRow
    $iLV_ItemCount   = _GUICtrlListView_GetItemCount($hListView)    ; GUICtrlSendMsg($ListView, $LVM_GETITEMCOUNT, 0, 0)
    $iLV_ColumnCount = _GUICtrlListView_GetColumnCount($hListView)  ;_SendMessage(GUICtrlSendMsg($ListView, $LVM_GETHEADER, 0, 0), 0x1200)
    If $iLV_ItemCount <= 0 Then Return ''
    ; преобразуем коды символов, если передана не строка
    If IsInt($sHorSepHeader) Then $sHorSepHeader = Chr($sHorSepHeader)
    If IsInt($sColumnSep)    Then $sColumnSep    = Chr($sColumnSep)
    If IsInt($sRowSep)       Then $sRowSep       = Chr($sRowSep)

    Local $aDataColumns[$iLV_ColumnCount][3]
    For $i = 0 To $iLV_ColumnCount-1
        $aLV_TextColumn = _GUICtrlListView_GetColumn($hListView,$i)
        $aDataColumns[$i][0] = $aLV_TextColumn[5]            ; текст заголовка колонки
        $aDataColumns[$i][1] = StringLen($aLV_TextColumn[5]) ; длина  текста заголовка колонки
        $aDataColumns[$i][2] = StringLen($aLV_TextColumn[5]) ; максимальная длина текста в строке пункта колонки, начальное значение - длина текста заголовка колонки
    Next

    ; если был передан массив максимальных значений длин текста пунктов колонок, то используем эти значения
    If Ubound($aArrayMax)>= $iLV_ColumnCount Then
        For $i=0 To $iLV_ColumnCount-1
            If $aArrayMax[$i]> $aDataColumns[$i][1] Then $aDataColumns[$i][2]=$aArrayMax[$i]
        Next
    ; иначе вычисляем максимальные значения перебором всего списка
    Else
        For $iLV_IndexItem = 0 To $iLV_ItemCount -1
        $aLV_TextRows = _GUICtrlListView_GetItemTextArray($hListView, $iLV_IndexItem)
            If Not IsArray($aLV_TextRows) Then ContinueLoop
            For $i = 0 To $aLV_TextRows[0]-1
                $iLenRow = StringLen($aLV_TextRows[$i+1])
                If $iLenRow > $aDataColumns[$i][2] Then
                    $aDataColumns[$i][2]= $iLenRow
                EndIf
            Next
        Next
    EndIf

    For $i=0 To $iLV_ColumnCount-1
        $sHeader &= StringFormat('%-' & ($aDataColumns[$i][2]+$CountSpace) & 's', $aDataColumns[$i][0]) & $sColumnSep
    Next

    $iWidthHeader = StringLen($sHeader)
    For $i = 1 To $iWidthHeader
        $sLine &= $sHorSepHeader
    Next
    $sFormatText &= $sLine   & @CRLF
    $sFormatText &= $sHeader & @CRLF
    $sFormatText &= $sLine   & @CRLF

    For $iLV_IndexItem = 0 To $iLV_ItemCount -1
    $aLV_TextRows = _GUICtrlListView_GetItemTextArray($hListView, $iLV_IndexItem)
        If Not IsArray($aLV_TextRows) Then ContinueLoop
        For $i = 0 To $aLV_TextRows[0]-1
            $sFormatText&=StringFormat('%-' & $aDataColumns[$i][2] + $CountSpace & 's',$aLV_TextRows[$i+1]) & $sRowSep
        Next
        $sFormatText &= @CRLF
    Next
    $sFormatText &= $sLine & @CRLF

    ; добавляем в конец таблицы число строк и дату\время
    If $sAddingStr Then
        Local $sStr1 = 'Total count: ' & $iLV_ItemCount
        Local $sStr2 = 'TimeStamp: ' & @MDAY & '.' & @MON & '.' & @YEAR & ' ' & @HOUR & '.' & @MIN
        Local $iMaxWidth = $iWidthHeader-Stringlen($sStr2)
        $sFormatText &= StringFormat('%-' & $iMaxWidth & 's', $sStr1) & $sStr2 &  @CRLF & $sLine
    EndIf
    ;ConsoleWrite('_SaveListAsTxt:' & TimerDiff($hTimer) & @CR)
    Return $sFormatText
EndFunc


На выходе имеем строку, которую можно сохранить в файл или вставить в буфер обмена, а затем в текстовый редактор. Визуально текст будет выглядеть так:
(нажмите для показа/скрытия)


Код: AutoIt [Выделить]
;Вызывать либо так:
Local $sText = _SaveListAsTxt($ListView)
;либо так:
Local $aTest[4]=[70,10,10,70] ; массив на четыре колонки - каждое значение максимальная длина строки текста в колонке.
Local $sText = _SaveListAsTxt($ListView,$aTest[4])


Как указано в шапке функции, вариант с передачей массива заранее определенных максимальных значений длины строк пунктов  работает быстрее (в 1.5 -2 раза), так как скрипту не нужно полностью перебирать весь список (для определения указанных значений это,  как вы понимаете, единственный способ).
Разница становится заметна на списках с более 1000-2000 строк. На списки в 100-200 строк дополнительный перебор оказывает минимальное по времени влияние.



« Последнее редактирование: Март 03, 2014, 01:52:45 от erlik »

Русское сообщество AutoIt


 

Похожие темы

  Тема / Автор Ответов Последний ответ
14 Ответов
7171 Просмотров
Последний ответ Март 11, 2010, 17:38:49
от Yashied
10 Ответов
5963 Просмотров
Последний ответ Март 04, 2011, 18:19:33
от gora
18 Ответов
14548 Просмотров
Последний ответ Сентябрь 18, 2011, 20:49:26
от Zalman1980
14 Ответов
6013 Просмотров
Последний ответ Ноябрь 14, 2011, 14:47:44
от Math
1 Ответов
1470 Просмотров
Последний ответ Ноябрь 03, 2013, 00:59:34
от ivsatel
10 Ответов
3788 Просмотров
Последний ответ Сентябрь 05, 2015, 14:59:25
от Kasper
5 Ответов
1250 Просмотров
Последний ответ Март 04, 2017, 08:02:15
от reset86
0 Ответов
549 Просмотров
Последний ответ Декабрь 05, 2017, 10:20:02
от zz0
1 Ответов
202 Просмотров
Последний ответ Август 31, 2018, 15:01:54
от musicstashall
2 Ответов
151 Просмотров
Последний ответ Январь 15, 2019, 16:50:22
от Mihail10