
Функции сохранения и загрузки параметров с примером использования
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
| function main()
local FPath = getScriptPath()..'//.params'
-- Создание таблицы для примера
local Params = {}
Params.a = 10
Params.b = 'qwerty'
Params.c = true
Params.d = {}
Params.d[1] = 100
Params.d[2] = 'asdfg'
Params.d[3] = false
Params.d[4] = {
['a'] = 10,
['b'] = 'qwerty',
['c'] = true
}
-- Сохраняет таблицу в файл
SaveTable(Params, FPath)
-- Загружает таблицу из файла
local NewParams = LoadTable(FPath)
if NewParams ~= nil then message(NewParams.d[4].b) end -- выведет "qwerty"
end
-- Сохраняет таблицу в файл
SaveTable = function(Table, FilePath)
local Lines = {}
local level = 0
function Rec(a)
local first = true
level = level + 1
local s = '' for i=1,level do s = ' '..s end
for key, val in pairs(a) do
if not first then Lines[#Lines] = Lines[#Lines]..',' end
local k = '[\''..key..'\']'
if type(key) == 'number' then k = '['..key..']' end
if type(val) ~= 'table' then
if type(val) == 'string' then
val = '\''..val..'\''
else
val = tostring(val)
end
table.insert(Lines, s..k..'='..val)
first = false
else
table.insert(Lines, s..k..'={')
first = false
Rec(val)
table.insert(Lines, s..'}')
level = level - 1
end
end
end
table.insert(Lines, 'local a = {')
Rec(Table)
table.insert(Lines, '}')
table.insert(Lines, 'return a')
local f = io.open(FilePath, 'w')
for i=1,#Lines do
f:write(Lines[i]..'\n')
f:flush()
end
f:close()
end
-- Загружает таблицу из файла
LoadTable = function(FilePath)
local func, err = loadfile(FilePath)
if not func then
message('Ошибка загрузки таблицы из файла: '..err)
return nil
else
return func()
end
end |
Данный пример создаст файл ".params" (можно открыть Блокнотом, это обычный текстовый файл, можете назвать его как угодно) со следующим содержимым:
local a = {
['a']=10,
['d']={
[1]=100,
[2]='asdfg',
[3]=false,
[4]={
['a']=10,
['c']=true,
['b']='qwerty'
}
},
['c']=true,
['b']='qwerty'
}
return a
Если у Вас появились какие-то вопросы, задайте их в комментариях под статьей !!!
Здравствуйте. Пробую использовать загрузку и сохранение таблицы. При остановке скрипта выводится ошибка "bad argument #1 to 'for iterator' (table expected, got nil)" на строку "for key, val in pairs(a) do". Что может быть?
Здравствуйте. То и значит, вместо таблицы вы передаете "ничто" - nil
В чем ошибка?
Нужно перестать пользоваться функциями SaveTable/LoadTable.
Вам подойдут функции из этого примера https://quikluacsharp.ru/nuzhnye-funktsii/comment-page-3/#comment-28751
Ваш фрагмент кода ошибку не может сгенерировать, событие OnStop не наступает и функция SaveTable не вызывается.
Ну да ладно, вы в Onstop передаете вместо таблицы - t_id, которое имеет тип 'number'.
А ошибка говорит про 'nil'.
Ваш фрагмент кода ошибку не может сгенерировать, событие OnStop не наступает и функция SaveTable не вызывается.
Ну да ладно, вы в Onstop передаете вместо таблицы - t_id, которое имеет тип 'number'.
А ошибка говорит про 'nil'.
Для того, что бы сохранить пользовательскую таблицу в файл нужно считать с нее данные в lua-таблицу и уже ее сохранять
Разве событие OnStop не наступает когда останавливаю скрипт? Чем отличается пользовательская таблица от Lua таблицы? И еще нужно таблицу преобразовать в строку а потом только сохранять в файл?
Что преобразуют данные функции в строку?
function table.val_to_str (v)
function table.key_to_str (k)
function table.tab_to_str(tbl)
function table.arr_to_str(tbl, s)
В чем разница function table.save_to_read(directory, tbl) от function table.save_to_load(directory, tbl)?
Мне нужно использовать function table.save_to_load(directory, tbl)?
"Разве событие OnStop не наступает когда останавливаю скрипт?" - наступает, но в вашем случае main не содержит бесконечного цикла и завершается сразу после запуска скрипта, без события OnStop, которое возникает при нажатии на кнопку "остановить" в окне доступных скриптов.
По названиям функций вроде понятно - преобразуют: таблицы, ключи и значения в формат, нужный для сохранения в файл, для последующего чтения.
Пользовательская таблица, это не lua, а визуальная форма у нее есть функции интерфейса, типа SetCell.
Считываете из ячеек значения и присваиваете их в свою таблицу, например:
table.tab_to_str(tbl) лучше использовать для файлов, которые вы сами читать не будете, разве что в процессе отладки своего скрипта,
которые так же будут считаны и преобразованы в lua-таблицу функцией table.read
Спасибо, буду пробовать)
Пожалуйста. Вы скачайте пример по ссылке и по экспериментируйте в нем используя table.msg
Пробую использовать функцию function table.arr_to_str(tbl, s), выдает ошибку " 'end' expected near '0'" на строку table.sort(rnum, function (a, b) return tonumber(a) 0 then. Что может быть?
выводится ошибка "attempt to index a nil value" на "row[c] = GetCell(t_id, r, c).image or """. что не так?
Не знаю, у меня все ровно работает. Теги "LUA - LUA" работают с ошибкой. Попробуйте так
function table.val_to_str (v)
if "string" == type( v ) then
v = string.gsub( v, "\n", "\\n" )
if string.match( string.gsub(v,"[^'\"]",""), '^"+$' ) then
return "'" .. v .. "'"
end
return '"' .. string.gsub(v,'"', '\\"' ) .. '"'
end
return "table" == type( v ) and table.tab_to_str( v ) or tostring( v )
end
function table.key_to_str (k)
if "string" == type( k ) and string.match( k, "^[_%a][_%a%d]*$" ) then
return k
end
return "[" .. table.val_to_str( k ) .. "]"
end
function table.tab_to_str(tbl)
if type(tbl)~='table' then return table.val_to_str(tbl) end
local result, done = {}, {}
for k, v in ipairs( tbl ) do
table.insert( result, table.val_to_str( v ) )
done[ k ] = true
end
for k, v in pairs( tbl ) do
if not done[ k ] then
table.insert( result, table.key_to_str( k ) .. "=" .. table.val_to_str( v ) )
end
end
return "{" .. table.concat( result, "," ) .. "}"
end
function table.arr_to_str(tbl, s)
local result, done= {"{"}, {}
for i = 1, #tbl do
if type(tbl[i]) == "table" then
local str = table.concat(table.arr_to_str(tbl[i], s.." "), ",\n")
result[#result+1] = s..table.key_to_str(i).."= "..str:gsub("{,", "{")
else
result[#result+1] = s..table.key_to_str(i).."= "..table.val_to_str(tbl[i])
end
done[i] = true
end
local rnum = {}
for k, v in pairs(tbl) do
if not done[k] and tonumber(k) then
rnum[#rnum+1] = k
done[k] = true
end
end
if #rnum > 0 then
table.sort(rnum, function (a, b) return tonumber(a) 0 then
-- table.sort(rstr, function (a, b) return a < b end)
for i=1, #rstr do
local k = rstr[i]
if type(tbl[k]) == "table" then
local str = table.concat(table.arr_to_str(tbl[k], s.." "), ",\n")
result[#result+1]= s..table.key_to_str(k).."= "..str:gsub("{,", "{")
else
result[#result+1]= s..table.key_to_str(k).."= "..table.val_to_str(tbl[k])
end
end
end
result[#result + 1] = s:sub(1, #s-1).."}"
return result
end
function table.save_to_read(directory, tbl)
if type(tbl) ~= "table" then return end
local f= io.open(directory, 'w'); if not f then return end
local r = table.arr_to_str(tbl, "")
table.remove(r, 1); table.remove(r, #r)
f:write(table.concat(r,",\n")); f:flush(); f:close()
end
function table.save_to_load(directory, tbl)
if type(tbl) ~= "table" then return end
local f= io.open(directory, 'w'); if not f then return end
local r = table.arr_to_str(tbl, "")
table.remove(r, 1)
f:write("{\n"..table.concat(r,",\n")); f:flush(); f:close()
end
function table.read(directory)
--преобразует строку: "key=val," в таблицу
local f = io.open(directory, "r")
if not f then
sleep(1)
f = io.open(directory, "r")
if not f then return end
end
local str = "{"..f:read("*a").."}"; f:close()
local fn = loadstring("return "..str)
if type(fn) == "function" then
return fn()
end
end
function table.load(directory)
--преобразует строку: "{key=val,}" в таблицу
local f = io.open(directory, "r")
if not f then
sleep(1)
f = io.open(directory, "r")
if not f then return end
end
local str = f:read("*a"); f:close()
local fn = loadstring("return "..str)
if type(fn) == "function" then
return fn()
end
end
function table.msg(tbl, slp)
if type(tbl) ~= "table" then
tbl = {tostring(tbl)}
end
local p = getScriptPath().."\\logmsg.txt"
table.save_to_read(p, tbl)
os.execute("start /I "..p)
local slp = slp or 5000
sleep(slp)
end
function main()
CreateTable()-- Создает таблицу
while not exitflag do
--Функция возвращает «true», если окно с таблицеи «t_id» закрыто
if IsWindowClosed(t_id) then break end
local t = {}
local rows, cols = GetTableSize(t_id)
-- message(tostring(rows).." "..tostring(cols))
for r = 1, rows do
local row = {}
for c = 1, cols do
row[c] = GetCell(t_id, r, c).image or ""
end
t[r] = row
end
table.msg(t, 3000)
end
end
function CreateTable()--- Функция создает таблицу
-- Получает доступный id для создания
t_id = AllocTable()
-- Добавляет 2 колонки
AddColumn(t_id, 1, "Дата", true, QTABLE_INT_TYPE, 30)
AddColumn(t_id, 2, "Средства", true, QTABLE_INT_TYPE, 30)
-- Создаем
CreateWindow(t_id)
-- Даем заголовок
SetWindowCaption(t_id, "Баланс")
-- Добавляет строку
InsertRow(t_id, -1)
SetWindowPos(t_id, 0, 0, 349, 263)-- Задаем позицию окна
end
function OnStop()
exitflag = true
DestroyTable(t_id)
return 1000
end
Все равно та же ошибка lua:18: attempt to index a nil value
Посмотрите внимательнее на свой пример и мой.
у вас Дата имеет столбец с индексом = 0, а такого индекса не существует в пользовательской таблице.
SetCell(t_id, st, 0, tostring(vr)) - вот это никуда и ничего не присвоит.
создать строку таблицы нужно прежде, чем ее заполнить значениями:
st = InsertRow(t_id, -1)
SetCell(t_id, st, 1, tostring(vr)) - так будет получше, чем у вас
и вот так:
table.save(t,"C:\\Users\\Александр\\Desktop\\трейдинг\\Скрипты\\balance.txt")
не пойдет.
во первых, таблица "t" в OnStop не видна, т.к. она объявлена локально в другом блоке - в main.
во вторых, скрипты обязательно! нужно держать в папках, имена которых не содержат кириллицы и магических символов.
С сохранением разобрался, а вот загружать не получается... что не так делаю?
навскидку, у вас столбцы int_type
вставка значения в ячейку этого типа выглядит так:
SetCell(t_id, r, c, tostring(rows[c]), rows[c])
пробовал, не работает...
потому что у вас строка добавлена одна, при создании формы, а в логе наверное чутка поболее строк, судя по туму, что вы используете OnFuturesClientHolding(fut_pos).
Считывайте на запуске одноименною таблицу, формируете строки, считываете файл, вставляете данные.
Но нужно понимать, что в таблице "futures_client_holding" строки могут не совпадать со строками, которые в файле.
Нужна проверка на валидность, по коду инструмента и торговому счету.
Как считать из массива на сколько строк будет таблица? Сколько строк будет содержать "t"? Чтобы в новую создаваемую таблицу добавить нужное колличество строк
Это вам нужно просто выучить мат-часть
https://quikluacsharp.ru/bez-rubriki/s-chego-nachat/
https://quik2dde.ru/viewtopic.php?id=16
А вы не скажите, можно ли создавать гистограмму в отдельном окне на основе данных из таблицы?
можно написать индикатор и добавить его на график или сделать еще таблицу с большим кол-вом строк/столбцов и заливать цветом нужные ячейки
Как можно из файла получать данные в индикатор и строить линию на основе их? Что то примеры найти не могу.
Данные из файла вы получать умеете.
Примеры есть:
https://quikluacsharp.ru/wp-content/uploads/2016/04/Sozdanie-indikatorov-tehnicheskogo-analiza-s-pomoshhyu-skriptov-Lua.pdf
да я этим уже воспользовался, но не знаю пока как присваивать линии значения из таблицы. нужно использовать функцию SetValue?
Какова роль в этой ситуации оператора fn = loadstring("return " ..fn)? Может всё дело в логике его работы?
Вы в ответ на его комментарий вопрос задайте, иначе он его не увидит.
Здравствуйте!
строка 6: считываем в переменную fn весь файл формата:
a=10, b={a=10},
т.к. это строка, то добавляем ей фигурные скобки, но это пока не таблица луа.
строка 7: создаем функцию fn, которая при выполнении вернет из строки таблицу луа
строка 12: возвращаем результат выполнения функции fn(), т.е. таблицу:
{a=10, b={a=10}}
А какой переменной вы присвоите эту таблицу - ваша забота))
Я уже давно переделал под другие нужды эти функции, и не могу найти, где последний раз их использовал.
local fn = "{"..f:read("*a").."}" --вот это выражение у меня уже без фигурных скобок
Спасибо большое за уделенное внимание и ценные советы! Буду дальше разбираться. Мощная штука, надо все понять))). Поплыл на регулярных выражениях(((. Сижу, копаю. С Вашего позволения еще потом могу обратиться с вопросом?
Не за что, обращайтесь
Уважаемый Kalikazandr, здравствуйте! Прошу пояснить в части, касающейся регулярных выражений, которые вы применили в своем коде:
Заранее спасибо за уделенное внимание)!
Фишка в том, что в луа таблице пара: ключ = значение - и ключ и значение могут быть чем угодно, соответственно, что бы правильно сделать сохранение (и, что главное, что бы потом все это дело считать правильно из файла) необходимо, проверить и заменить/дополнительно экранировать с начала переменной и до ее конца, обрезать лишние пробелы. Например:
path={}
path._Orders = 'C:\\lua_modules\\Orders.lua'
или так
path["C:\\lua_modules\\Orders.lua"] = {hint = "лог заявок",{sec_code="SBER",price = 100,qty=10,balance=10}}
Выражение '^"+$' познаково с начала и до конца строки
Не тратьте на это время. Научитесь сохранять, считывать.
Когда ваш алгоритм начнет приносить прибыль, то вам не понадобится знание всех тонкостей луа - за не надобностью. Пить пиво на пляже можно и без знания захватов для форматирования строки)) Я в свое время зря потратил на это время, и на самом деле уже и подзабыл - за не надобностью)))
Спасибо большое, Kalikazandr, за помощь!)))
Рад помочь)
Уважаемый kalikazandr, добрый вечер! Учитывая ваш опыт, не подскажите, интересует такой вопрос. Необходимо для дела выделить цветом текст (число) и подчеркнуть его цветной двойной чертой. Можно конечно всё организовать через клетки таблицы (значения собраны в таблицу) - раскрашивать с помощью SetColor, но уж очень интересно - есть ли в QLua (Lua) такие или приблизительно такие средства для String'ов), чтобы не загромождать таблицу цветовыми схемами? Спасибо! С уважением, Алексей!
Здравствуйте, к сожалению такой способ мне не известен и спец-символов в луа таких нет. Возможно вам стоит посмотреть в сторону юникода и функции string.gsub (s, pattern, repl [, n]).
Но оно того стоит?))) По времени дешевле закрасить ячейку.
Спасибо большое за уделенное время! Похоже, вы правы, проще будет раскрасить ячейку, тем более можно расцветить не только фон ячейки, но и сам текст - прекрасная альтернатива. Попробовал поискать по string.gsub - применение символов Юникода дает богатые возможности, но есть много "НО", чтобы их учесть нужно многое предусмотреть, возможно даже от чего-то отказаться в реализации. Не хотелось бы.
Некоторое время назад нашел (по прошлой теме) - https://github.com/hoelzro/ansicolors - может быть интересно.
Свои вопросы оставил на полях кода, надо пролистать вправо, неудобно, не предусмотрел, согласен.
Добрый день, kalikazandr! Хочу спросить не по теме. Вы не сталкивались с необходимостью вывода в одну таблицу Quik'а данных в динамике (к примеру - объемы) по нескольким инструментам. Какие подводные камни могут быть? И возможно ли это в принципе без каких-либо временных коллизий и потерь? Суть в том, чтобы изменения данных по свече не в новую строку записывать, а в уже выделенную строку под неё. Свеча закрывается, данные перестают записываться в старую ячейку, добавляется строка или просто переход на новую, уже добавленную строку, данные начинают писаться туда, в соответствующую ячейку. Данные по разным инструментам задумка писать в одну строку - соответственно временному интервалу.
День добрый! Нет проблем,
если строки - это время - выбранный таймфрейм, то и с источника данных в нужную строку добавляйте все изменения по нужному параметру.
Спасибо! Я тоже такого же мнения, но, чувствую, надо будет повозиться. По крайней мере, с первого раза не все получилось))). С уважением!
День добрый!
Сделайте таблицу формата:
local curr_rows = {posix1 = 1, posix2 = 2, posixN = N},
где posix это время в секундах, округленное до нужного таймфрейма(ТФ), а значения - ссылки на № строк в таблице.
Тогда получив новое значение нужного параметра, округляете текущее время до нужного ТФ,
из таблиц квик:
local item = getItem("all_trades", getNumberOf("all_trades")-1)
local posix = math.floor(os.time(item.datetime)/60)*60 -- округлили до 1 минуты (так можно <= М60)
local row = curr_rows[posix] -- получили № строки, в которую нужно сделать запись.
Если со свечек берете данные, то там уже время округлено до ТФ, просто в секунды перевести.
Здорово! Спасибо!
Всегда пожалуйста.
Kalikazandr, добрый день! Хотел вам написать на почту. Как узнать ваш адрес? Алексей.
Добрый!
kalikazandr@mail.ru
Kalikazandr, добрый вечер! Подскажите, маленько подвис в задаче: опираясь на вашу идею пытаюсь в таблицу добавить строку ключ - тайм-фрейм, значение - номер строки в пользовательской таблице, вроде posix1=1 и т.д. Пытаюсь это сделать через table.insert / table.sinsert. Не получается. Синтаксис для добавления строки с пользовательским ключом (в моем случае - тайм-фрейм) мне найти и подобрать не удалось. Может вы подскажите направление, куда смотреть? С уважением!
Или отказаться от table.insert в пользу других способов создания и инициализации? Почему-то не хочется.
Добрый вечер!
table.insert служит для добавления элемента массива:
tab = {"a", 1, "C"} эквивалентно {[1] = "a", [2] = 1, [3] = "C"}
print(tab[2]) = > 1
table.insert(tab, 2, "Вася")
print(tab[2]) = > Вася
А у вас не массив, тем паче использовать потокобезопасный table.sinsert - плохая идея без нужды.
local curr_rows = {posix1 = 1, posix2 = 2, posixN = N} -- из примера выше не массив
При инициализации вам нужно достать текущий datetime свечи, например вот такой он будет на 15-й торговой минуте ТФ = 1М:
local datetime = {year = 2018, month = 1, day = 18, hour = 10, min = 15} -- 2018/01/18 10:15
local posix = os.time(datetime) -- 1516259700 создали будущий ключ строки
curr_rows[posix] = 15 -- где 15 - № строки в вашей таблице, соответствует 15 минуте
Когда появился новый бар, нужно:
1) Разово добавить в curr_rows ссылку на строку таблицы - curr_rows[1516259760] = 16
2) Разово добавить саму 16-ю строку в таблицу.
Если не разберетесь, пишите на почту, сделаю пример. Тут сайт переделывает луа-код как ему хочется и возникнут новые вопросы.
Kalikazandr, добрый день! Спасибо за уделенное время и силы). Вашу идею уловил. К table.sinsert я обратился именно из-за его особенности (потокобезопасности) для того, чтобы на границе тайм-фреймов (окончание предыдущего - начало следующего) скрипт не перепутал строку, в которую надо вставить данные. По скольку поток информации достаточно плотный и обновляется быстро, а инструмент не один (минимум - два), то возможна ситуация, когда на границе тайм-фрейма изменения придут по обоим инструментам с мизерной разницей и оба передадут сигнал в таблицу соответствия на добавление новой строки с одинаковой [тайм-фрейм] = № строки - конфликт, ведь уникальность не контролируется! Вся сложность для меня в том, чтобы в момент начала поступления информации по инструментам на новой "свече" в таблице соответствия уже была новая запись (для нового бара) - вот это пока я не смог осилить. Может я чего не понял, просто не все проверил практически... Кстати, а call-back появления новой "свечки" есть встроенный? Спасибо за предложение помощи! Если совсем упрусь - буду знать). А как можно узнать адрес Вашей электронной почты?
Привет!
table.sinsert нужна для обмена данными между потоками. В вашем случае поток один и хоть 300 инструментов будет у вас в таблице - пофик вообще.
проверку делаете при: первый кто увидел новый бар:
if not curr_rows[posix] then
row = InsertRow(t_id, -1)
curr_rows[posix] = row
end
И усё)
Спасибо! Пробую)!
Пожалуйста!
Прошу прощения за свою "темноту" - поток соответствует включенному скрипту или функции внутри скрипта? Такая каша в голове...
По простому так:
поток №1 - main
поток №2 - все что не в main выполняется (функции обратного вызова, например)
Разумеется, если вообще можно.
Дмитрий, здравствуйте! Пытаюсь разобрать код, который в качестве оптимизации предложил kalikazandr, 20 мая 2016 года. Очень интересно, но в силу новизны для меня этого языка сложно полностью понять суть предложения. Для начала интересует функция считывания из файла настроек. Никак не могу получить тот самый элемент - NewParams.d[4].b с помощью кода предложенного kalikazandr. Можете провести аналогию между вашим и его вариантами кода? Где может быть тот самый нюанс?)
Здравствуйте! Задайте лучше этот вопрос автору комментария, он обычно отвечает на вопросы.
Дмитрий, добрый вечер! Не подскажите, интересует такой вопрос. Необходимо для дела выделить цветом текст (число) и подчеркнуть его цветной двойной чертой. Можно конечно всё организовать через клетки таблицы (значения собраны в таблицу) - раскрашивать с помощью SetColor, но уж очень интересно - есть ли в QLua (Lua) такие или приблизительно такие средства для String'ов), чтобы не загромождать таблицу цветовыми схемами? Спасибо! С уважением, Алексей!
Добрый вечер! Такого простого способа не знаю, думаю можно попробовать string.char https://quikluacsharp.ru/qlua-osnovy/funktsii-raboty-so-strokami-v-qlua-lua/ и посмотреть коды символов в гугле, есть готовые символы с подчеркиванием, метод так себе, но, возможно, задачу решит 🙂
Спасибо большое! Посмотрел string.char, тяжеловато выглядит - может быть это опыт (т.е. его отсутсвие). Проще будет раскрасить ячейку, тем более можно расцветить не только фон ячейки, но и сам текст - прекрасная альтернатива. Применение символов Юникода дает богатые возможности (визуальные), но есть много "НО", чтобы их учесть нужно многое предусмотреть, возможно даже от чего-то отказаться в реализации. Не хотелось бы. Ещё раз спасибо!
Всегда пожалуйста! К сожалению не все возможности требуемые предоставляет QLua
Дмитрий, добрый день. Подскажите, как считать конкретную строку файла?
Добрый день! Выведет 10-ю строку файла:
Спасибо за оперативный ответ! То, что нужно!
Всегда пожалуйста!
Дмитрий, добрый день!
Правильно ли я понимаю что строки:
SaveTable = function(Table, FilePath) и
LoadTable = function(FilePath) - просто описание функций и их можно заменить на обычные (привычные):
function SaveTable (Table, FilePath) и
function LoadTable (FilePath)?
Добрый день, да, Вы правильно понимаете.
Возможно кому-то, наверно, и мне пригодится запись в статье "ПЕРЕМЕННЫЕ, МАССИВЫ И ФУНКЦИИ В QLUA (LUA)" о такой форме записи при определении функции ~
MyFunc = function(Param1, Param2) ;
Спасибо!
Спасибо, добавил!
Этот код подойдет для сохранения данных скрипта между запусками?
Читайте название заголовка статьи 🙂
К примеру,скрипт Баланс покупок/продаж, таймфрейм 1 час.
Данный код сохраняет массив (таблицу lua) в файл, когда Вы вызываете функцию SaveTable и загружает таблицу из файла (если он существует), когда Вы вызываете функцию LoadTable, а какой массив Вы сохраните в файл это от Вас зависит, а не от скрипта.
Ясно.Спасибо.
Всегда пожалуйста!
Стырила нижевыложенный код и вставила в скрипт Баланс Покупок и продаж в функцию Main.Все работает и сохраняется.Я даже технически не понимаю пока всего как и что,буду разбираться.Не посмотрите,насколько корректно получилось?
Что-то мне кажется Вы усложнили себе задачу. Вставьте просто функции SaveTable и LoadTable в конец своего скрипта, создайте какой-нибудь массив, в котором Вы будете хранить параметры, которые нужно сохранять между перезапусками. Добавьте в скрипт функцию OnStop, в ней вызывайте SaveTable, передавая туда Ваш массив на сохранение. И добавьте функцию OnInit, в ней вызывайте функцию LoadTable, которая возвратит Вам Ваш сохраненный массив. Вот и все.
Привет.
Вопрос можно ли переменные SC_ записать в одну строку что то типа
и потом прочитать их?
Привет, а почему нет?
не знаю как записать
Можешь и так записать, только в конце добавь символ конца строки
А потом читай, примерно вот так
Пока не получилось буду пробовать дальше
Что не получается?
считывать
Ну если прям вообще не будет получаться, то выкладывай код, посмотрим
запись так
вставь между 5 и 6 строками
message(tostring(line))
а между 9 и 10 строками
message(tostring(str))
посмотри что считывается
А файл открывал? В нем что-то есть?
Разобрался ошибка как всегда идиотская:
было
надо
а код правильно работает, спасибо
Да, так всегда и бывает 🙂 Всегда пожалуйста!
Здравствуйте, Дмитрий!
Попробовал данный код для хранения настроек в csv файле.
Все работает, кроме одного:
Если в ячейке пусто, то этот элемент между точками с запятой (пустая строка) просто игнорируется.((
И пятый элемент становится четвертым и так далее.
Это мне понадобилось при ручной правке csv файла в Экселе.
Данный код никакого отношения к CSV не имеет, не представляю как Вы его с CSV задействовали 🙂
Делайте как-то чтобы между точкой с запятой был пробел, тогда эксель не должен проигнорировать
Нет, дело не в этом, вы не поняли, Дмитрий.
Скрипт Lua сохраняет файл в csv с разделителями точка с запятой.
Эксель нормально открывает этот файл.
Если пользователь сотрет какие-то значения в ячейках, то Эксель сохранит их тоже нормально
рассмотрим файл в одну строку и 4 ячейки:
ААА;BBB;;DDD
Так вот данный код проигнорирует 4 элемент и DDD станет третьим при разборе строки.
Вся проблема возникает при ручном редактировании csv в Экселе.
Пустая строка нулевой длины скриптом разбора игнорируется.
Просто Вы комментарий под статьей написали, которая не имеет отношения к CSV 🙂
Пардон, искал по кусочку кода в Яндексе.
Я помню, что этот чудесный способ хранения таблиц в csv файле я позаимствовал у вас.
Просто я часто редактирую вечером эти файлы csv в Экселе, вот и столкнулся с данной неприятностью.
Ничего страшного, просто я не сразу понял 🙂
Пока выкручиваюсь, добавляя после каждой точки с запятой собаку и убирая ее на этапе разбора строки на комплектующие.))
--line='100;200;aaa;bbb;ccc' -- В этом случае все нормально.
line='100;200;aaa;;mmm' -- В этом случае прозевывает пустую строку.
line=string.gsub(line,";",";@") -- Добавил справа от кадо1 точки с запятой собаку.
vyh=''
for str in line:gmatch("[^;^\n]+") do
str=string.gsub(str,'@','') -- Убрал все собаки из отделенного элемента.
vyh=vyh.."/"..tostring(str)
end
message(vyh)
Тоже вариант
Ну а в общем и целом, спасибо Вам, Дмитрий, за то что вы есть. ))
Немного подхалимажа не помешает.)))
Всегда пожалуйста 🙂
Время вопроса (коментария) вижу, но может кому пригодится вариант попроще
Добрый день, Дмитрий.
Очень громоздкий и медленный подход вы избрали для сохранения таблицы в файл.
a=10 и ['a']=10 одно и тоже.
Не проще вот такие функции использовать?
и чтение:
Одной из моих задач была еще и та, чтобы получался читабельный файл, с отступами и т.д. Возможно по этому мой код на 10 строк больше, чем в Вашем примере.
Дело не в 10 или 20 строках или читабельности, а в практичности lua.
Если грамотно использовать эти функции, то читабельность в файле будет лучше, чем у вас, а вот по скорости сохранения раз в 30 быстрее (поначалу лепил такой же примерно код как у вас), объем получаемого файла меньше на лишние скобки, "return a" и прочее не нужное барахло : )
Согласитесь, если файл настроек велик или файл будет содержать хеш таблицу с данными за последние 30-40 торговых дней, то прирост в скорости будет заметен визуально. Для небольших файлов безусловно пойдет и ваш код.
Да, наверное Вы правы. Я для сохранения параметров скрипта это делал, а не для сохранения больших объемов данных, для данных нужно другое решение, однозначно.
При навешивании assert на loadstring начинает сообщать о недопустимых символах у параметра local в сформированной строке?! Правда, считываемый файл формируется кодом Дмитрия, а не вашим. Может дело в этом?
Приблизительно понял, все в моем понимании сошлось на ином формате записей файла, ваш код сохранения таблицы работает несколько иначе. Теперь буду думать, как работает часть кода, сохраняющая данные. Спасибо за подкинутую мудрую идею.
Уважаемый Kalikazandr, здравствуйте! Пытаюсь разобрать код, который вы в качестве оптимизации предложили 20 мая 2016 года по предмету промежуточного сохранения данных в период выключения. Мне это очень интересно, но в силу новизны для меня этого языка сложно полностью понять суть предложения. Для начала интересует функция считывания из файла настроек. Никак не могу получить тот самый элемент - NewParams.d[4].b с помощью вашего кода. Скрипт работает, а вот ожидаемого сообщения с информацией о содержимом указанного элемента нет. Можете поподробнее описать суть этого кода, провести аналогию, соответствие между вашим вариантом кода и вариантом Дмитрия? Какова роль в этой ситуации оператора fn = loadstring("return " ..fn)? Может всё дело в логике его работы?
Дмитри, извиняюсть чт приу вам на русскосм.
Виороё1ё ден изуса. Luna yне ради пражздлд
Я, честно говоря, не понял что Вы написали, может быть английскими буквами лучше напишите, если у Вас проблема с русской раскладкой.