1

Тема: AHK: Загрузка базы в ListView

Доброго времени суток, форумчане!

Возникла небольшая проблема в работе с "ListView", саму таблицу создал, всё прекрасно, но как туда занести данные извне? :-)

Есть вот такой текстовый файлик-база.

Требуется занести данные вот в эту таблицу:

Gui, Add, ListView, r20 w700 , №|data3|RequestDate|data1|remont|Master|asc|inj|kod1|kod2|kod3|kod4|ClientName|ClientAdress|ClientPhone|PhoneIMEI|ClientName1

Всё что я смог, это "вынести" данные с базы в переменные, но для этого требовалось ввести как минимум, 1 данное "dog":

#NoEnv
FilePath = D:\Input.txt ; указать путь к текстовому файлу

dog = 604463
Items = 

data1,data3,Rem,remont,Master,asc,inj,kod1,lvl,kod2,kod3,kod4,RequestDate,Disrepair3,ClientName,ClientAddress,PersonPhone,PersonIMEI,ClientName1

FileRead, Text, % FilePath

RegExMatch(Text, "s)dog:[ \t]*" dog ".*?End", Found)
Loop, parse, Items, `,, %A_Space%
{
   RegExMatch(Found, "s).*?" A_LoopField ":[ \t]*(.*?)\R", %A_LoopField%)
   %A_LoopField% := %A_LoopField%1
}

2

Re: AHK: Загрузка базы в ListView

Примерно так:

InputFile = D:\Input.txt

Items := "№|data3|RequestDate|data1|remont|Master|asc|inj|kod1|kod2|kod3|"
      . "kod4|ClientName|ClientAddress|ClientPhone|PhoneIMEI|ClientName1"
Gui, Add, ListView, r20 w700, % Items
      
StringReplace, Items1, Items, №, dog
StringReplace, Items1, Items1, ClientPhone, PersonPhone

FileRead, Text, %InputFile%
StartPos := 1
Loop
{
   StartPos := RegExMatch(Text, "s)(^|\$End)(.*?)\$End", Found, StartPos) + 1  ; сдвигаем стартовую позицию
   if !Found2
      Break
      
   Loop, parse, Items1, |
   {
      RegExMatch(Found2, "im`a)" A_LoopField ":[ \t]*(.*)$", Found)
      %A_LoopField% := Found1
   }
   LV_Add("", dog, data3, RequestDate, data1, remont, Master, asc, inj
            , kod1, kod2, kod3, kod4, ClientName, ClientAddress 
            , PersonPhone, PhoneIMEI, ClientName1)
}

Loop 17
   LV_ModifyCol(A_Index, "AutoHdr")

Gui, Show

У тебя в файле PersonPhone, а в скрипте заголовок столбца — ClientPhone (нужна лишняя операция по замене); в файле ClientAddress, в скрипте — ClientAdress (исправил).

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3 (изменено: Skare, 2011-08-22 17:00:29)

Re: AHK: Загрузка базы в ListView

А, да, простите, я не заметил:( Опечатался значит:-) .
Прекрасно работает! А можно ли сделать так, что бы при двойном клике на какую-либо строку, выполнялось какое-нибудь действие с этими данными, например вывод их в окошке через "MsgBox"?

4

Re: AHK: Загрузка базы в ListView

В справке всё написано.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

5

Re: AHK: Загрузка базы в ListView

Ещё раз огромное спасибо, с этим разобрался:-). Но возникли ещё некоторые вопросы:
Как сделать так, что бы при выделении какой-либо строки в таблице и нажатии ентера, производилось то же действие, что и тут с дабл кликом:

MyListView:
if A_GuiEvent = DoubleClick
{
    LV_GetText(dog,A_EventInfo,1)
    LV_GetText(data3,A_EventInfo,2)
    LV_GetText(RequestDate,A_EventInfo,3) 
    LV_GetText(data1,A_EventInfo,4) 
    LV_GetText(rem,A_EventInfo,5) 
    LV_GetText(remont,A_EventInfo,6) 
    LV_GetText(Master,A_EventInfo,7) 
    LV_GetText(Disrepair3,A_EventInfo,8) 
    LV_GetText(asc,A_EventInfo,9) 
    LV_GetText(inj,A_EventInfo,10) 
    LV_GetText(kod1,A_EventInfo,11) 
    LV_GetText(lvl,A_EventInfo,12) 
    LV_GetText(kod2,A_EventInfo,13) 
    LV_GetText(kod3,A_EventInfo,14) 
    LV_GetText(kod4,A_EventInfo,15) 
    LV_GetText(ClientName,A_EventInfo,16) 
    LV_GetText(ClientAddress,A_EventInfo,17) 
    LV_GetText(PersonPhone,A_EventInfo,18) 
    LV_GetText(PhoneIMEI,A_EventInfo,19) 
    LV_GetText(ClientName1,A_EventInfo,20) 

}
return

?
Можно ли обновлять таблицу в режиме реального времени?:) Или хотя бы отдельной кнопочкой?
Можно ли как-нибудь редактировать данную таблицу? Что бы при этом в том "файлике-базе" так же изменялась\добавлялась информация?:-)
Пока всё, на эти вопросы в справке я ответа не нашёл(либо я был крайней невнимателен).

6

Re: AHK: Загрузка базы в ListView

Обновлять можно в любом режиме с помощью функций LV_Modify(), LV_Insert() и т. п. Редактировать вручную можно только первую колонку. Для этого в ListView должны быть опция -ReadOnly. Уведомления о редактировании описаны здесь.

Skare пишет:

на эти вопросы в справке я ответа не нашёл(либо я был крайней невнимателен).

Это да!

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

7

Re: AHK: Загрузка базы в ListView

Немножко разобрался, но с этим:

Skare пишет:

Как сделать так, что бы при выделении какой-либо строки в таблице и нажатии ентера, производилось то же действие, что и тут с дабл кликом:

MyListView:
if A_GuiEvent = DoubleClick
{
    LV_GetText(dog,A_EventInfo,1)
    LV_GetText(data3,A_EventInfo,2)
    LV_GetText(RequestDate,A_EventInfo,3) 
    LV_GetText(data1,A_EventInfo,4) 
    LV_GetText(rem,A_EventInfo,5) 
    LV_GetText(remont,A_EventInfo,6) 
    LV_GetText(Master,A_EventInfo,7) 
    LV_GetText(Disrepair3,A_EventInfo,8) 
    LV_GetText(asc,A_EventInfo,9) 
    LV_GetText(inj,A_EventInfo,10) 
    LV_GetText(kod1,A_EventInfo,11) 
    LV_GetText(lvl,A_EventInfo,12) 
    LV_GetText(kod2,A_EventInfo,13) 
    LV_GetText(kod3,A_EventInfo,14) 
    LV_GetText(kod4,A_EventInfo,15) 
    LV_GetText(ClientName,A_EventInfo,16) 
    LV_GetText(ClientAddress,A_EventInfo,17) 
    LV_GetText(PersonPhone,A_EventInfo,18) 
    LV_GetText(PhoneIMEI,A_EventInfo,19) 
    LV_GetText(ClientName1,A_EventInfo,20) 

}
return

?

И так ничего не понял:(.

8

Re: AHK: Загрузка базы в ListView

Примечания к ListView:

Чтобы определить, когда была нажата клавиша Enter в то время, как ListView находился в фокусе, используйте кнопку по умолчанию...

В подпрограмме кнопки можно получить номера и текст выделенных строк, как объяснено здесь.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

9

Re: AHK: Загрузка базы в ListView

Вот получилось что-то похожее, но и так остались вопросы:(.

InputFile = D:\Input.txt
 
Items := "№|data3|RequestDate|data1|rem|remont|Master|Disrepair3|asc|inj|kod1|lvl|kod2|kod3|"
      . "kod4|ClientName|ClientAddress|PersonPhone|PhoneIMEI|ClientName1"

Gui, Add, Button, Hidden Default, OK
Gui, Add, ListView, r20 w700 gMyListView, % Items
 
StringReplace, Items1, Items, №, dog
 
FileRead, Text, %InputFile%
StartPos := 1
Loop
{
   StartPos := RegExMatch(Text, "s)(^|\$End)(.*?)\$End", Found, StartPos) + 1  ; сдвигаем стартовую позицию
   if !Found2
      Break
 
   Loop, parse, Items1, |
   {
      RegExMatch(Found2, "im`a)" A_LoopField ":[ \t]*(.*)$", Var)
      %A_LoopField% := Var1
   }
   LV_Add("", dog, data3, RequestDate, data1, rem, remont, Master, Disrepair3, asc, inj
            , kod1, lvl, kod2, kod3, kod4, ClientName, ClientAddress 
            , PersonPhone, PhoneIMEI, ClientName1)
}
 
Loop 17
   LV_ModifyCol(A_Index, "AutoHdr")


Gui, Show,, New GUI Window2
return

ButtonOK:
RowNumber := LV_GetNext(0,F)
    LV_GetText(dog,RowNumber,1)
    LV_GetText(data3,RowNumber,2)
    LV_GetText(RequestDate,RowNumber,3) 
    LV_GetText(data1,RowNumber,4) 
    LV_GetText(rem,RowNumber,5) 
    LV_GetText(remont,RowNumber,6) 
    LV_GetText(Master,RowNumber,7) 
    LV_GetText(Disrepair3,RowNumber,8) 
    LV_GetText(asc,RowNumber,9) 
    LV_GetText(inj,RowNumber,10) 
    LV_GetText(kod1,RowNumber,11) 
    LV_GetText(lvl,RowNumber,12) 
    LV_GetText(kod2,RowNumber,13) 
    LV_GetText(kod3,RowNumber,14) 
    LV_GetText(kod4,RowNumber,15) 
    LV_GetText(ClientName,RowNumber,16) 
    LV_GetText(ClientAddress,RowNumber,17) 
    LV_GetText(PersonPhone,RowNumber,18) 
    LV_GetText(PhoneIMEI,RowNumber,19) 
    LV_GetText(ClientName1,RowNumber,20)
MsgBox  %dog% %data3% %data1% %rem% %Master%
return


GuiClose:
ExitApp


MyListView:
if A_GuiEvent = DoubleClick
{
    LV_GetText(dog,A_EventInfo,1)
    LV_GetText(data3,A_EventInfo,2)
    LV_GetText(RequestDate,A_EventInfo,3) 
    LV_GetText(data1,A_EventInfo,4) 
    LV_GetText(rem,A_EventInfo,5) 
    LV_GetText(remont,A_EventInfo,6) 
    LV_GetText(Master,A_EventInfo,7) 
    LV_GetText(Disrepair3,A_EventInfo,8) 
    LV_GetText(asc,A_EventInfo,9) 
    LV_GetText(inj,A_EventInfo,10) 
    LV_GetText(kod1,A_EventInfo,11) 
    LV_GetText(lvl,A_EventInfo,12) 
    LV_GetText(kod2,A_EventInfo,13) 
    LV_GetText(kod3,A_EventInfo,14) 
    LV_GetText(kod4,A_EventInfo,15) 
    LV_GetText(ClientName,A_EventInfo,16) 
    LV_GetText(ClientAddress,A_EventInfo,17) 
    LV_GetText(PersonPhone,A_EventInfo,18) 
    LV_GetText(PhoneIMEI,A_EventInfo,19) 
    LV_GetText(ClientName1,A_EventInfo,20)
    MsgBox  %dog% %data3% %data1% %rem% %Master%
}

Можно ли как-то объединить

ButtonOK:
RowNumber := LV_GetNext(0,F)
    LV_GetText(dog,RowNumber,1)
    LV_GetText(data3,RowNumber,2)
    LV_GetText(RequestDate,RowNumber,3) 
    LV_GetText(data1,RowNumber,4) 
    LV_GetText(rem,RowNumber,5) 
    LV_GetText(remont,RowNumber,6) 
    LV_GetText(Master,RowNumber,7) 
    LV_GetText(Disrepair3,RowNumber,8) 
    LV_GetText(asc,RowNumber,9) 
    LV_GetText(inj,RowNumber,10) 
    LV_GetText(kod1,RowNumber,11) 
    LV_GetText(lvl,RowNumber,12) 
    LV_GetText(kod2,RowNumber,13) 
    LV_GetText(kod3,RowNumber,14) 
    LV_GetText(kod4,RowNumber,15) 
    LV_GetText(ClientName,RowNumber,16) 
    LV_GetText(ClientAddress,RowNumber,17) 
    LV_GetText(PersonPhone,RowNumber,18) 
    LV_GetText(PhoneIMEI,RowNumber,19) 
    LV_GetText(ClientName1,RowNumber,20)
MsgBox  %dog% %data3% %data1% %rem% %Master%
return

и

MyListView:
if A_GuiEvent = DoubleClick
{
    LV_GetText(dog,A_EventInfo,1)
    LV_GetText(data3,A_EventInfo,2)
    LV_GetText(RequestDate,A_EventInfo,3) 
    LV_GetText(data1,A_EventInfo,4) 
    LV_GetText(rem,A_EventInfo,5) 
    LV_GetText(remont,A_EventInfo,6) 
    LV_GetText(Master,A_EventInfo,7) 
    LV_GetText(Disrepair3,A_EventInfo,8) 
    LV_GetText(asc,A_EventInfo,9) 
    LV_GetText(inj,A_EventInfo,10) 
    LV_GetText(kod1,A_EventInfo,11) 
    LV_GetText(lvl,A_EventInfo,12) 
    LV_GetText(kod2,A_EventInfo,13) 
    LV_GetText(kod3,A_EventInfo,14) 
    LV_GetText(kod4,A_EventInfo,15) 
    LV_GetText(ClientName,A_EventInfo,16) 
    LV_GetText(ClientAddress,A_EventInfo,17) 
    LV_GetText(PersonPhone,A_EventInfo,18) 
    LV_GetText(PhoneIMEI,A_EventInfo,19) 
    LV_GetText(ClientName1,A_EventInfo,20)
    MsgBox  %dog% %data3% %data1% %rem% %Master%
}

?
Как можно заметить, действия здесь выполняются одни и те же, но переменные определяются по разному.

10

Re: AHK: Загрузка базы в ListView

Как-нибудь так:

ButtonOK:
MyListView:
if (A_ThisLabel = "MyListView" && A_GuiEvent != "DoubleClick")
	Return
	
RowNumber := A_ThisLabel = "ButtonOK" ? LV_GetNext() : A_EventInfo
    LV_GetText(dog,RowNumber,1)
    LV_GetText(data3,RowNumber,2)
    LV_GetText(RequestDate,RowNumber,3) 
    LV_GetText(data1,RowNumber,4) 
    LV_GetText(rem,RowNumber,5) 
    LV_GetText(remont,RowNumber,6) 
    LV_GetText(Master,RowNumber,7) 
    LV_GetText(Disrepair3,RowNumber,8) 
    LV_GetText(asc,RowNumber,9) 
    LV_GetText(inj,RowNumber,10) 
    LV_GetText(kod1,RowNumber,11) 
    LV_GetText(lvl,RowNumber,12) 
    LV_GetText(kod2,RowNumber,13) 
    LV_GetText(kod3,RowNumber,14) 
    LV_GetText(kod4,RowNumber,15) 
    LV_GetText(ClientName,RowNumber,16) 
    LV_GetText(ClientAddress,RowNumber,17) 
    LV_GetText(PersonPhone,RowNumber,18) 
    LV_GetText(PhoneIMEI,RowNumber,19) 
    LV_GetText(ClientName1,RowNumber,20)
MsgBox  %dog% %data3% %data1% %rem% %Master%
Return
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

11

Re: AHK: Загрузка базы в ListView

Имеется вопрос, очень близкий по названию к теме.

Нужно взять данные из базы (массива данных) и создать в GUI элемент ListView. Массив имеет вид:
parameter_1 = nsdfseioprj
parameter_2 = baglkjfdnsb
parameter_3 = gsjrgsljgjsd
parameter_4 = ndsjfgnldfgl
parameter_5 = dfdfsgidifog

Известно количество столбцов в ListView и их имена .
Содержимое строк соответствует значению переменных parameter_1, parameter_2 и так далее. Число параметров известно.
Требуется добавлять в элемент ListView строки. Согласно справке, это делается при помощи функции для строк LV_Add([Options, Field1, Field2, ...]). В данном отдельно взятом случае это будет выглядеть так:

LV_Add( , parameter_1, parameter_2, parameter_3, parameter_4, parameter_5)

Основная трудность в том, что каждый раз изменяется количество параметров (parameter_...). Здесь их пять, а в следующий раз их может быть десять, сто и т. д. Нужно, чтобы программа динамически корректировала команду LV_Add.

Конечно, можно заранее написать длиннющую строку

LV_Add( , parameter_1, parameter_2, parameter_3, parameter_4, parameter_5 и так далее до parameter_100500) ; чтобы точно хватило

Но это как-то не правильно.

12

Re: AHK: Загрузка базы в ListView

ypppu
Видимо, либо создавать текст скрипта динамически, писать во временный файл и запускать, либо работать с ListView через API. Может, всё-таки проще прописать параметров с запасом? 100 колонок — это абсурд какой-то, по-моему. Что, реально может быть так много?

13

Re: AHK: Загрузка базы в ListView

Нет, на практике такого не предвидится (разве что при ошибке пользователя). Просто хотелось узнать, вдруг всё уже придумано до нас.
Если число параметров (колонок) превысит 20, программа спросит: "Число колонок превышает 20. Продолжить? [Да] / [Нет]".
Если число параметров (колонок) дойдёт до 200, программа скажет: "Достигнут предел 200 колонок".
В документации говорится, что для ListView ограничение 200 колонок. Я прописал команду на 200 параметров. Когда закончу, посмотрю, как это влияет на производительность.

14

Re: AHK: Загрузка базы в ListView

ypppu пишет:

Основная трудность в том, что каждый раз изменяется количество параметров (parameter_...). Здесь их пять, а в следующий раз их может быть десять, сто и т. д. Нужно, чтобы программа динамически корректировала команду LV_Add.

Если я правильно понял, то нужно просто через строку параметры передавать. Пример:

AddRow(Data, Delimiters=",")
{
   CurColCount := LV_GetCount("Column")
   LV_Add("")
   CurRowCount := LV_GetCount()
   Loop, parse, Data, %Delimiters%
   {
	  if(A_Index>CurColCount)
	     LV_InsertCol(A_Index, "", "column_" . A_Index)
	  LV_Modify(CurRowCount, "Col" . A_Index, A_LoopField)
   }
   LV_ModifyCol()
   return
}

Gui, Add, ListView, r10 w480 , one|two
Gui, Show
AddRow("раз,два,три,четыре")
AddRow("раз,два,три,четыре,пять,шесть")
AddRow("раз;два;три;четыре;пять;шесть;семь;восемь", ";")
return

Esc::
GuiClose:
ExitApp

Тут функция AddRow добавляет строку в текущий ListView, принимая параметры в виде текстовой строки. Разделитель параметров передаётся во втором параметре, по-умолчанию используется запятая. Ну и разумеется через WinApi можно и будет в разы быстрее .