Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

UoKit.com Форумы _ UO Pilot _ Работа с базой TXT

Автор: Ksardeks 18.7.2017, 21:26

Есть задача: Вытащить текст и редактировать TXT файл след. образом - Вырезать первую строку с текстом, записать ее в значение пилота. И чтобы это срабатывало каждый раз, каждое вырезание текста было с новой строки. Не побрезгую подключением плагинов.
Содержание файла:

Код

Текст1
Текст2
Текст3
Текст4
Текст5

После вырезания строки файл становится:
Код

Текст2
Текст3
Текст4
Текст5

в значении записано "Текст1"
После вырезания строки файл становится:
Код

Текст3
Текст4
Текст5

в значении записано "Текст2"
и т.д.

Автор: cirus 19.7.2017, 2:38

Код
load_array %arr "D:\UOPilot\file.txt"   // загрузить массив
// %arr [1]   - первая строка из файла
// %arr [2]   - вторая строка
               // и т. д.
log clear
log mode compact
    // вывести в лог все строки из файла
for #i 1 size(%arr)
    log %arr [#i]    
end_for
end_script

Есть какой-то смысл удалять строки по одной?

Автор: Ksardeks 19.7.2017, 8:33

Получается содержимое документа выгружается в программу? Работать на прямую с текстовым документом и редактировать его не получится?
Просто есть база номеров 100к строк, с ней и работать. И важно чтобы если что-то собьется все можно было продолжить с момента прерывания. Иначе придется резать фаил по 1к строк)

Автор: veiron 19.7.2017, 10:54

я сохраняю работу с номером последней строкой в файл, потом запускаю с этой строки. Хотя может кто что-то лучшее подскажет, так идет постоянная перезапись файла, после каждой строки.

Автор: cirus 19.7.2017, 12:14

Номер строки, с которой работали, можно записывать в буфер. Если скрипт в какой-то момент остановить, то потом можно получить номер строки из буфера и загрузить массив с указанной строки.

Код
set #count 1          // с какой строки загружать массив
get clipboard %tmp      // получить содержимое буфера
if is_real(%tmp[1]) = 1    // если в буфере число
    set #count %tmp[1]     // то присвоить его переменной #count
end_if
hint Номер строки: #count
load_array %arr 1,1,#count,1,0,0 "C:\Users\abc\Desktop\123.txt"    // загрузить массив с указанной строки

// для примера, выводим в лог по 2 строки из файла при каждом запуске скрипта
for #i 1 2
    set #count #count + 1
    set clipboard #count       // записали в буфер номер строки, с которой работали
    log %arr [#i]                 // вывести в лог строку
end_for
end_script

Автор: veiron 19.7.2017, 14:19

А если комп вырубило, буфер будет пустой ведь? Тогда как быть?

Автор: cirus 19.7.2017, 15:07

Цитата
А если комп вырубило, буфер будет пустой ведь? Тогда как быть?

В таком случае и результат работы со строками не сохранится и придётся делать сначала.
Можно периодически сохранять результаты, тогда же записывать в отдельный файл номер строки, на которой остановились. Это явно лучше чем перезаписывать файл 100к раз.

Автор: veiron 19.7.2017, 17:28

Цитата(cirus @ 19.7.2017, 15:07) *

В таком случае и результат работы со строками не сохранится и придётся делать сначала.
Можно периодически сохранять результаты, тогда же записывать в отдельный файл номер строки, на которой остановились. Это явно лучше чем перезаписывать файл 100к раз.

Как записать к примеру номер строки если пилот выключить через диспетчер задач или выдернуть шнур из розетки? У меня сейчас к примеру файл с 5к мылом, при вводе каждого идет сохранение номера строки с этим мылом, и так за время работы пилота перезапись идет 5к раз.

Автор: Cockney 19.7.2017, 20:41

Никак. Пропадает электричество, соответственно все завершается аварийно. Без сохранения. Можно записывать каждые 50-100 единиц обработанных данных. Но точное число получить нельзя в принципе.

Автор: oxavi 25.9.2017, 10:56

Цитата(cirus @ 19.7.2017, 15:07) *

В таком случае и результат работы со строками не сохранится и придётся делать сначала.
Можно периодически сохранять результаты, тогда же записывать в отдельный файл номер строки, на которой остановились. Это явно лучше чем перезаписывать файл 100к раз.



привет у меня есть вопрос а можно сделать так что бы скрипт получился к примеру такой

было копирование одной строки с переносом в приложения далее вставляем

за тем делаем копирование следующий строки ????

Автор: DarkMaster 25.9.2017, 11:55

схема по сути будет той же самой. Если там нет чего-то сверх экстримального (база на пару гигов), то проще загрузить файл и работать уже с загруженным массивом. Если база огромна, то схема будет та же самая, просто загружать придется частями.

Автор: Чекист 8.3.2019, 13:18

Ребята, почему если брать текст с блокнота через массив,

Код
load_array %arr "D:\Работа\uopilot\insta\tovar.txt"

то русский текст вставляется иероглифами?

Вот пример.

Код
load_array %arr "D:\Работа\uopilot\insta\tovar.txt"   
    kleft 155, 145 abs
    for #i 1 size(%arr)
    send %arr [#i]
    sendex {Enter}
    end_for
end_script  



И как мне в этом случае брать из блокнота определенный текст и заставить бота его вставлять в определенное место?

Автор: cirus 8.3.2019, 13:30

Цитата
то русский текст вставляется иероглифами?

Пересохранить файл в кодировке ansi, а не unicode.
Файл, сохранить как, кодировка ANSI.

Автор: Чекист 8.3.2019, 13:46

Цитата(cirus @ 8.3.2019, 14:30) *

Пересохранить файл в кодировке ansi, а не unicode.
Файл, сохранить как, кодировка ANSI.


Спасибо тебе большое, что ты на протяжении с 2012 года, активно мне отвечал и помогал! Ты лучший!

Автор: Чекист 9.3.2019, 16:54



Вот код, который я использую, для вывода сообщений на экран.

Код

load_array %arr "D:\Работа\uopilot\insta\tovar.txt"  
    kleft 155, 145 abs
    for #i 1 size(%arr)
    send %arr [#i]
    sendex {Enter}
    end_for
end_script  


Но есть большая проблема, нельзя использовать и русский и английский шрифт, так как если включена английская раскладка, он будет выдавать текст английским буквами в независимости от того, текст написан на русском или английском и с русской раскладкой противоположная ситуация. Есть ли выход с такой проблемы? sad.gif

Автор: cirus 9.3.2019, 18:16

Код
say "Русский текст"
say "English text"
end_script

Напечатает то что нужно независимо от раскладки.

Автор: Чекист 9.3.2019, 20:52

Цитата(cirus @ 9.3.2019, 19:16) *

Код
say "Русский текст"
say "English text"
end_script

Напечатает то что нужно независимо от раскладки.

Спасибо!Работает! rolleyes.gif

Автор: Чекист 10.3.2019, 16:00

Ребята, в чем может быть проблема? На основном компьютере написал бота с командой say , все отлично на нем работало - перенес на другой комп через тимвиевер, запустил, команда say перестала вводить слова, я изменил ее на sendex - слова вводиться, поставил обратно say - вроде заработало, потом подправил скрипт - say снова перестала работать....В чем может быть проблема?

И второй вопрос, я сохранил все слова в блокнот в формате ANSI, но потом в блокнот начал вносить символы из другого языка (индийского) с буквам: ç ü и т.д. При сохранении их в блокноте - они меняют эти иероглифы на стандартные буквы. Как это обойти? Что бы я мог вводить из блокнота и рус и англ и индийские слова?

Заранее, очень благодарен за ответ!

Автор: cirus 10.3.2019, 16:50

Для say нужна привязка к окну.
ANSI поддерживает только латиницу и кириллицу. Остальные языки только unicode. Пилот не работает с unicode.
Возможно на lua можно как-то сделать, не знаю.




Автор: DarkMaster 11.3.2019, 1:50

Цитата
Возможно на lua можно как-то сделать, не знаю.

Для луа есть модули для работы с юникодом. Но проблема в том, что отправлят то все равно пилотовскими функциями будем...

Автор: cirus 11.3.2019, 14:03

Цитата
отправлят то все равно пилотовскими функциями будем

SendMessageW для lua нет? Можно WM_CHAR отправлять.

Автор: DarkMaster 11.3.2019, 17:25

Вот так попробуй:

Код
do
    local back = package.path
    package.path = "luaPlugins\\winapi\\?.lua;"..package.path
    setfenv(1, require'winapi')
    local window = require[[winapi.window]]
    package.path = back
end

SendMessagePtr(hwnd, WM, wParam, lParam)

Какие параметры туда пихать я хз. Открыл справку майкрософта - проблевался и ушел. Появилось стойкое желание убивать.
Цитата
wParam

Type: WPARAM

Additional message-specific information.

lParam

Type: LPARAM

Additional message-specific information.

Примеры дайте. Куда какие коды помещать. В каких случаях. У них то первые два байта бесполезные то вторые, в каком виде. Справка охренительная - в параметры помещаются параметры. Правда?

Автор: Cockney 11.3.2019, 20:39

Что-то ты прям обгадил мелкомягких. Нехорошо. И зря.

Не с того края ты начал. Начинать надо с того, что за оконная система и как она работает.

Так как у нас оконная система, то управляется она посылкой сообщений. Сообщения делятся на системные и юзерские. Т.к. число только системных сообщений велико уже само по себе, то для охвата всех вообще был придуман SendMessage() с двумя параметрами опционными. Отсюда вытекает, что вот этой функции вообще пофиг что слать и смотреть то надо на само сообщение, как например на https://docs.microsoft.com/en-us/windows/desktop/inputdev/wm-char, где в красках все проиллюстрировано.


В юзерских мессаджах это дает маршалинг любых данных между окошками.

Автор: DarkMaster 11.3.2019, 21:41

тогда уж https://docs.microsoft.com/en-us/windows/desktop/inputdev/wm-unichar

Цитата
Не с того края ты начал. Начинать надо с того, что за оконная система и как она работает.

Я знаю что это и как это работает. Но честно, я не переношу на дух мсовские хелпы. Если на англ еще что-то понятно, то когда они начинают придумывать собственную терминологию давно прижившихся определений (см русские хелпы) или делать хелпы для галочки с названием "моя_великая_галка": включает и выключает "мою_великую_галку", либо выкдивает сообщения "позовите адмнинистратора" мне хочется убивать. Да, может они великие и прекрасные, но не для меня. Я когда-то по апи много читал, и кой что писал, но, к сожалению, читать обычно можно все что угодно, но только не родные маны. Все выше сказанное мои личные тараканы, не на что больше это не претендует и заведомо не претендовало, в т.ч. в ранее написанных постах.

Автор: Cockney 11.3.2019, 21:52

Так русские хелпы машиным переводом сделаны ? По крайней мере около года назад было уведомление. И если на английском понятно, то не понимаю изначально суть претензии к мс по поводу что куда.

Автор: cirus 12.3.2019, 3:09

Цитата
Примеры дайте. Куда какие коды помещать.

Код
SendMessagePtr(workwindow(), 0x0102, 0x41, 1)   -- англ. буква 'А'
SendMessagePtr(workwindow(), 0x0102, 0x410, 1)  -- русская буква 'А' (смотрим таблицу кодов символов юникод)

Ругается на первый параметр. Что должно быть?

Автор: DarkMaster 12.3.2019, 6:32

Цитата
Так русские хелпы машиным переводом сделаны ?

они не ограничиваются msdn'ом, но еще и поставляются с по и имеют локализацию.
Цитата
Ругается на первый параметр. Что должно быть?

Вообще хендл =)
Код
function SendMessagePtr(hwnd, WM, wParam, lParam)
    if wParam == nil then wParam = 0 end
    if type(lParam) == 'nil' then lParam = 0 end
    return C.SendMessageW(hwnd, flags(WM),
        ffi.cast('WPARAM', wParam),
        ffi.cast('LPARAM', lParam))
end

Это собственно вся функция.
Ругается оно на невозможность привести число к укащателю структуру. Структура объявлена:
struct HWND__ { int unused; }; typedef struct HWND__ *HWND;

Автор: DarkMaster 12.3.2019, 7:05

https://docs.telerik.com/teststudioapi/html/T_ArtOfTest_Common_Win32_HWND.htm
Properties
Name Description
Public property Children
Public property ClassName
Public property Descendants
Public property HINSTANCE
This is useful because some frameworks store their DLL instance handle here, allowing you to loosely identify the framework that is managing the window.
Public property Id
Public property IsEnabled
Public property IsNull
Public property IsWindow
Public property Owner
Public property Parent
Public property ProcessId
Public property Root
Public property RootOwner
Public property Text
Public property ThreadId
Public property WindowRect
Gets or sets the dimensions of the bounding rectangle of the specified window. The dimensions are given in screen coordinates that are relative to the screen origin.

Автор: DarkMaster 12.3.2019, 9:16

Напрямую можно вот так дергать функцию:
C.SendMessageW

Автор: rinat84 12.3.2019, 10:44

WM_CHAR отправляет в окна символы от 0 до 254, то есть у кодов выше 255 будет обрезаться верхняя часть.
можно обойти разбив код символа на 2 части по 2 байта и отправлять 2 раза WM_CHAR на один Unicod символ
smile.gif

Автор: DarkMaster 12.3.2019, 11:00

Осталось понять каким образом дернуть hwnd в пределах Lua. EnumWindows и FindWindow вроде как отсутсвуют. GetFocus();GetActiveWindow(); возвращают null.

Автор: cirus 12.3.2019, 11:12

Цитата
WM_CHAR отправляет в окна символы от 0 до 254

Это SendMessageA. SendMessageW нормально отправляет коды символов юникода.

Автор: Чекист 5.4.2019, 18:50

Ребята, используя скрипт:

Код

load_array %arr "D:\Работа\uopilot\insta\tovar.txt"  
    kleft 155, 145 abs
    for #i 1 size(%arr)
    send %arr [#i]
    sendex {Enter}
    end_for
end_script    




Как мне сделать так, что бы он брал текст с tovar.txt первую строку, копировал ее, после чего, я ее вставлял куда надо, и записать этот скопированный текст с первого блокнота в другой блокнот tovar2.txt, а потом пилот должен удалить первую строку с tovar.txt (использованный текст) и сместить второй текст со второй строки на первую в tovar.txt.


Как я понял, старт этой темы был именно про это, но я так и не догнал как это сделать...


Заранее, очень благодарен за ответ!

Автор: cirus 6.4.2019, 1:36

Код
load_array %arr "D:\Работа\uopilot\insta\tovar.txt"  // загрузить массив

//log %arr[1]    // первая строка из файла
write ("D:\Работа\uopilot\insta\tovar2.txt" %arr [1]\r\n)   // записываем в файл tovar2.txt
delete_array %arr -1  // удалить первую строку из массива
save_array %arr "C:\Users\yacir\Desktop\tovar.txt"  // записать массив в файл
end_script

Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)