Forum.iFiction.Ru

iFiction.Ru · ifHub · FAQ · IFWiki · QSP · URQ · INSTEAD · AXMA

форум об interactive fiction, текстовых приключенческих играх и всём таком...

Вы не зашли.

0    0    #1
30.12.2010 21:13

Olegus t.Gl.
Участник (+1053, -249)
Откуда: Москва
Зарегистрирован: 01.03.2001
Сообщений: 2879
Вебсайт

Модуль для работы с таблицами данных

Пару-тройку дней назад присутствовал при дискуссии 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 'Таб.Удалить','Персонажи'

Прикрепленные файлы:
otg_lib_tables_v1_2.zip, Размер: 24,312 байт, Скачано: 880
otg_lib_tables_v1_3.zip, Размер: 25,449 байт, Скачано: 571
otg_lib_tables_v1_3_1.zip, Размер: 25,532 байт, Скачано: 1,117

Неактивен

2    0    #2
02.09.2014 05:25

Билли Бонс
Участник (+2)
Зарегистрирован: 23.08.2014
Сообщений: 8

Re: Модуль для работы с таблицами данных

Хотел сказать спасибо за модули, использовал модуль с меню, очень удобно. По поводу этого модуля возник такой вопрос про элемент "Номер строки":
Если использовать 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)

Неактивен

0    0    #3
02.09.2014 09:55

Билли Бонс
Участник (+2)
Зарегистрирован: 23.08.2014
Сообщений: 8

Re: Модуль для работы с таблицами данных

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').

Да, как вариант.

Неактивен

0    0    #4
10.09.2014 15:42

Билли Бонс
Участник (+2)
Зарегистрирован: 23.08.2014
Сообщений: 8

Re: Модуль для работы с таблицами данных

Спасибо

Неактивен

0    0    #5
04.11.2014 08:55

Билли Бонс
Участник (+2)
Зарегистрирован: 23.08.2014
Сообщений: 8

Re: Модуль для работы с таблицами данных

Такой вопрос:
Функция Таб.{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 и в результате глючит

Неактивен

0    0    #6
04.11.2014 16:31

Билли Бонс
Участник (+2)
Зарегистрирован: 23.08.2014
Сообщений: 8

Re: Модуль для работы с таблицами данных

Я делал следующую проверку:

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 строк из начала таблицы

Неактивен

0    0    #7
10.12.2014 06:24

Билли Бонс
Участник (+2)
Зарегистрирован: 23.08.2014
Сообщений: 8

Re: Модуль для работы с таблицами данных

Спасибо. Если не сложно, то какие процедуры изменились? Я у себя менял только код Таб.{IDСтроки}, как в сообщении 17. Вроде все тогда заработало. Что-то еще исправленно?

Неактивен

0    0    #8
01.02.2015 19:38

Билли Бонс
Участник (+2)
Зарегистрирован: 23.08.2014
Сообщений: 8

Re: Модуль для работы с таблицами данных

Сделал еще одно изменение:
В модуле 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)

Неактивен

0    0    #9
02.02.2015 01:55

Билли Бонс
Участник (+2)
Зарегистрирован: 23.08.2014
Сообщений: 8

Re: Модуль для работы с таблицами данных

Ну я описал выше. Пример:

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=

Что и должно быть, так как таблица пуста. Проблема была в том, что не обнулялся массив "Выборка" как я описал выше.

Неактивен

Powered by PunBB
© copyright 2001–2024 iFiction.Ru