Пару-тройку дней назад присутствовал при дискуссии goraph и Ajenta насчёт структур данных QSP. Под впечатлением от слов goraph, что ограничения работы с массивами, мешают написать настоящее текстовое RPG, набросал модуль работы с таблицами.
Данный модуль предоставляет следующие возможности:
Текущая версия: 1.3.1 (скачать)
Документация on-line: https://ifiction.ru/h/otg_lib_tables_help.html
Пример работы с таблицей:
GS 'Таб.Создать','Персонажи','Имя, Здоровье, Раса' GS 'Таб.СоздатьИндекс','Персонажи','Имя' GS 'Таб.ДобавитьСтроку','Персонажи','Крокодил',90,'Варвар' GS 'Таб.ДобавитьСтроку','Персонажи','Арабелла',77,'Амазонка' GS 'Таб.ДобавитьСтроку','Персонажи','Адельм',60,'Монах' GS 'Таб.ДобавитьСтроку','Персонажи','Каннибал',75,'Варвар' GS 'Таб.ДобавитьСтроку','Персонажи','Марина',77,'Амазонка' GS 'Таб.Сортировать', 'Персонажи', 'Раса,Здоровье-' GS 'Таб.Установить','Персонажи','Адельм','Здоровье',25 GS 'Таб.Выбрать','Персонажи','Раса','=','Варвар' :перебор_строк_таблицы if func('Таб.Следующая','Персонажи','Герой'): *NL func('Таб.Значение','Персонажи','Номер строки')+'. '+$Герой['Имя']+' ('+Герой['Здоровье']+')' JUMP 'перебор_строк_таблицы' end GS 'Таб.Удалить','Персонажи'
Неактивен
Хотел сказать спасибо за модули, использовал модуль с меню, очень удобно. По поводу этого модуля возник такой вопрос про элемент "Номер строки":
Если использовать Table.Select, то похоже нумерация строк сбивается
Например:
gs 'Table.Create', 'Test', 'Name, Number'
gs 'Table.NewLine', 'Test', 'Abc',1
gs 'Table.NewLine', 'Test', 'Abc',2
gs 'Table.NewLine', 'Test', 'Qwe',1
gs 'Table.NewLine', 'Test', 'Qwe',2
GS 'Table.Select','Test','Name','=','Qwe'
if func('Table.Next','Test'): LineNum=func('Table.Value','Test','Номер строки')
В этом случае в LineNum будет 1, а не 3. Если же вызвать строку c LineNum позже(например DeleteLine), то будет вызвана строка 'Abc',1, а не 'Qwe',1
Так задуманно? Проблема еще в том, что если создать численный индекс(1,2,3...), то функции типа GetValue интерпретируют цифровой параметр как номер строки, а не значение индексного поля, даже если я определил индекс. Плюс к тому, если стирать строки, то нумерация строк пересчитывается.
Есть ли какой-то простой способ установить каждой строке уникальный цифровой номер(типа autonumber), чтобы потом по нему можно было ссылаться, даже если часть строк трешь?
Еще в справке пропущено описание Table.LinesCount
Отредактировано Билли Бонс (02.09.2014 05:28)
Неактивен
Olegus t.Gl. написал:
Можно пример кода?
Например:
gs 'Table.Create', 'Test', 'Name, Number'
gs 'Table.NewLine', 'Test', 'Abc',1
gs 'Table.NewLine', 'Test', 'Abc',2
gs 'Table.NewLine', 'Test', 'Qwe',1
gs 'Table.NewLine', 'Test', 'Qwe',2
GS 'Table.Select','Test','Name','=','Qwe'
if func('Table.Next','Test'):
LineNum=func('Table.Value','Test','Номер строки')
func('Table.GetValue','Test',LineNum,'Name')
end
Выдает 'Abc', a не 'Qwe', как можно было бы ожидать. Если func('Table.GetValue','Test',LineNum,'Name') вызывается дальше по коду - результат тот же самый.
Olegus t.Gl. написал:
Правильно я понимаю, что ты хочешь иметь возможность использовать уникальный ID строки вместо номера строки во всех функциях, где номер строки является одним из параметров (типа GetValue из твоего вопроса)?
Да. В принципе, я добился того, чего хотел и имеющимися средствами (через FindValue), однако отсутствие id мне показалось нелогичным. Номер строки часто сбивается, и показывает вовсе не на ту строку, которую ожидаешь.
Olegus t.Gl. написал:
Проблему понял. Да, числовые значения воспринимаются как номер строки, а не значение индекса. Тут нужно подумать, как сделать лучше. Как вариант, для числовых значений индекса его можно указывать строкой: "index:3":
func('Table.GetValue','Test','index:2','Name')
. А для уникального ID строки так:func('Table.GetValue','Test','id:3','Name')
.
Да, как вариант.
Неактивен
Спасибо
Неактивен
Такой вопрос:
Функция Таб.{IDСтроки}
Вместо
if isnum($ARGS[14]):
Result=func('Таб.{IDСтроки}',$ARGS[0],val($ARGS[14]))
EXIT
end
Не должно ли быть вот так:
if isnum($ARGS[14]):
Result=val($ARGS[14])
EXIT
end
Если я правильно понял код, то в первом варианте функция путает номер строки и id и в результате глючит
Неактивен
Я делал следующую проверку:
gs 'Table.Create', 'Test', 'Name'
gs 'Table.NewLine', 'Test', 'A'
gs 'Table.NewLine', 'Test', 'B'
gs 'Table.NewLine', 'Test', 'C'
gs 'Table.NewLine', 'Test', 'D'
gs 'Table.NewLine', 'Test', 'E'
gs 'Table.NewLine', 'Test', 'F'
gs 'Table.DeleteLine', 'Test','id:1'
gs 'Table.DeleteLine', 'Test','id:3'
gs 'Table.DeleteLine', 'Test','id:4'
'By id:'+func('Table.GetValue','Test','id:5','Name')
'By num:'+func('Table.GetValue','Test',2,'Name')
В варианте
if isnum($ARGS[14]):
Result=val($ARGS[14])
EXIT
end
я получал
By Id:E
By Num:E
В варианте
if isnum($ARGS[14]):
Result=func('Таб.{IDСтроки}',$ARGS[0],val($ARGS[14]))
EXIT
end
Я получал
By Id:
By Num:C
По логике должно быть Е, у нее id=5 и она становится второй строкой после стирания 3 строк из начала таблицы
Неактивен
Спасибо. Если не сложно, то какие процедуры изменились? Я у себя менял только код Таб.{IDСтроки}, как в сообщении 17. Вроде все тогда заработало. Что-то еще исправленно?
Неактивен
Сделал еще одно изменение:
В модуле Table.Copy убрал строку
copyarr 'otg_Таблица_<<$ARGS[1]>>_Выборка', 'otg_Таблица_<<$ARGS[0]>>_Выборка'
а строку
copyarr 'otg_Таблица_<<$ARGS[1]>>_ТекущаяСтрока', 'otg_Таблица_<<$ARGS[0]>>_ТекущаяСтрока'
заменил на
dynamic "otg_Таблица_<<$ARGS[1]>>_ТекущаяСтрока=0"
Причина: если в таблице Source есть данные, но при копировании используется фильтр под который не подходит ни одна из строк, то таргет-таблица пустая, а вот ее выборка не пустая. Причем она не сбрасывается командой Table.Select, так как та сбрасывает выборку только если количество строк больше 0. В результате команды Table.Next и Table.Value по пустой таблице дают ненулевые результаты.
На всякие случай еще в Table.Select добавил после 5 строки
killvar 'otg_Таблица_<<$ARGS[0]>>_Выборка'
dynamic "otg_Таблица_<<$ARGS[0]>>_ТекущаяСтрока=0"
чтобы выборка сбрасывалась и если таблица пуста, так как возможно какте-то еще процедуры могут создать непустую выборку в пустой таблице
После исправления вроде все заработало
Отредактировано Билли Бонс (01.02.2015 21:11)
Неактивен
Ну я описал выше. Пример:
gs 'Table.Create', 'Test', 'Name'
gs 'Table.NewLine', 'Test', 'A'
gs 'Table.NewLine', 'Test', 'B'
gs 'Table.NewLine', 'Test', 'C'
gs 'Table.Select', 'Test'
gs 'Table.Copy', 'Test', 'TestTarget','Name','=','Z'
gs 'Table.Select','TestTarget'
'Next Res='+func('Table.Next','TestTarget')
'Value Res='+func('Table.Value','TestTarget','ID строки')
Выдает
Next Res=-1
Value Res=1
После исправления
Next Res=0
Value Res=
Что и должно быть, так как таблица пуста. Проблема была в том, что не обнулялся массив "Выборка" как я описал выше.
Неактивен