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 байт, Скачано: 873
otg_lib_tables_v1_3.zip, Размер: 25,449 байт, Скачано: 567
otg_lib_tables_v1_3_1.zip, Размер: 25,532 байт, Скачано: 1,113

Неактивен

0    0    #2
03.01.2011 11:39

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

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

Обновил модуль: добавил в архив документацию, почистил код, реализовал некоторые новшества.

Неактивен

0    0    #3
11.01.2011 14:27

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

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

Обновил модуль:

  • Исправлена ошибка в функции "Таб.УдалитьСтроку", из-за которой не все данные по строке удалялись из памяти.
  • Модуль поменял название с "otg_table" на "otg_tables".

Выложил документацию на сайт.

Неактивен

0    0    #4
14.01.2011 13:45

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

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

В архив добавил вариант модуля с англоязычными названиями операторов и функций. Внёс эту информацию в документацию.

Неактивен

0    0    #5
02.07.2013 12:02

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

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

Версия 1.2 (скачать):

Добавил в модуль команду "Таб.Сортировать". Теперь строки таблицы можно сортировать как по одной, так и по нескольким колонкам по возрастанию и убыванию.

Код:

GS 'Таб.Сортировать', 'Персонажи', 'Раса, Здоровье-'

Неактивен

2    0    #6
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    #7
02.09.2014 09:27

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

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

Билли Бонс написал:

По поводу этого модуля возник такой вопрос про элемент "Номер строки":
Если использовать Table.Select, то похоже нумерация строк сбивается
Так задуманно?
Есть ли какой-то простой способ установить каждой строке уникальный цифровой номер(типа autonumber), чтобы потом по нему можно было ссылаться, даже если часть строк трешь?

Да, так задумано. "Номер строки" возвращает порядковый номер строки. В твоём примере — в выборке. В принципе, без проблем можно добавить параметр "ID строки", который будет возвращать уникальный ID строки во всей таблице (благо, он такой есть), который не изменяется никогда, типа: func('Table.Value','Test','ID строки').
Правильно я понимаю, что ты хочешь иметь возможность использовать уникальный ID строки вместо номера строки во всех функциях, где номер строки является одним из параметров (типа GetValue из твоего вопроса)?

Билли Бонс написал:

Проблема еще в том, что если создать численный индекс(1,2,3...), то функции типа GetValue интерпретируют цифровой параметр как номер строки, а не значение индексного поля, даже если я определил индекс.

Проблему понял. Да, числовые значения воспринимаются как номер строки, а не значение индекса. Тут нужно подумать, как сделать лучше. Как вариант, для числовых значений индекса его можно указывать строкой: "index:3": func('Table.GetValue','Test','index:2','Name'). А для уникального ID строки так: func('Table.GetValue','Test','id:3','Name').

Билли Бонс написал:

Если же вызвать строку c LineNum позже(например DeleteLine), то будет вызвана строка 'Abc',1, а не 'Qwe',1

Можно пример кода?

Неактивен

0    0    #8
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    #9
02.09.2014 10:47

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

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') вызывается дальше по коду - результат тот же самый.

Ясно. 'Table.GetValue' работает с абсолютным порядковым номером строки во всей таблице. А в LineNum у тебя хранится относительный порядковый номер из выборки. При работе с выборкой нет средств указания конкретной строки именно из выборки — там все действия реализуются через перебор и относятся к текущей строке.
Полагаю, добавлением сущности уникального ID подобные проблемы можно будет снять.

На этой неделе сделаю.

Неактивен

0    0    #10
02.09.2014 18:04

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

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

Билли Бонс написал:

Еще в справке пропущено описание Table.LinesCount

Информация о функции "Table.LinesCount" справке была, но из-за ошибки в теге заголовка она "сливалась" с описанием предыдущей функции. Поправил тег, теперь всё хорошо: https://ifiction.ru/h/otg_lib_tables_he … LinesCount

Неактивен

0    0    #11
08.09.2014 22:26

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

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

Доработки сделал, внесу правки в документацию — выложу.

Неактивен

0    0    #12
10.09.2014 15:42

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

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

Спасибо

Неактивен

0    0    #13
13.09.2014 22:34

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

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

Olegus t.Gl. написал:

Доработки сделал, внесу правки в документацию — выложу.

Добрался до документации. Выложил обновлённый модуль (1.3):

  • Добавлена возможность получения уникального идентификатора строки и использование его при получении данных из таблицы.
  • Добавлена возможность работы с числовыми индексами.

Неактивен

0    0    #14
29.10.2014 19:28

testament
Участник
Зарегистрирован: 29.10.2014
Сообщений: 1

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

Не удается добавить  строку больше 8-и элементов

gs 'Table.NewLine', 'test', 1, 2, 3, 4, 5, 6, 7, 8 - все норм
Добавляешь 9-й элемент - Неверное число аргументов оператора / функции!

Неактивен

0    0    #15
31.10.2014 12:54

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

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

testament написал:

Не удается добавить  строку больше 8-и элементов

gs 'Table.NewLine', 'test', 1, 2, 3, 4, 5, 6, 7, 8 - все норм
Добавляешь 9-й элемент - Неверное число аргументов оператора / функции!

Это ограничение самой платформы QSP. Обсуждается тут.

Неактивен

0    0    #16
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    #17
04.11.2014 10:41

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

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 и в результате глючит

Нет, всё правильно. Все функции, в которых есть обращение к номеру строки, работают с абсолютным номером строки в таблице. Он же взят за ID. Поэтому функция при обращении по ID обращается по абсолютному номеру строки.

Однако, в данном модуле при удалении строки происходит сдвиг номеров строк — я не во всех своих решениях так делал именно для сохранения индексов — поэтому могут быть глюки, да. Так что мой косяк. Тут нужно подумать, как реорганизовать данные, чтобы такого не происходило. В принципе, это не особо сложно.

Неактивен

0    0    #18
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    #19
04.11.2014 23:50

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

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

Билли Бонс написал:

По логике должно быть Е, у нее id=5 и она становится второй строкой после стирания 3 строк из начала таблицы

Ну так я и говорю, что проблемы проявляются после удаления строк. Поправлю.

Неактивен

0    0    #20
07.12.2014 20:36

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

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

Ошибка с определением уникального идентификатора строки исправлена. Выложена версия 1.3.1.

Неактивен

0    0    #21
10.12.2014 06:24

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

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

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

Неактивен

0    0    #22
10.12.2014 10:05

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

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

Билли Бонс написал:

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

Только эта функция и изменена.

Неактивен

0    0    #23
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    #24
01.02.2015 23:06

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

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

Билли Бонс написал:

После исправления вроде все заработало

А что именно не работало?

Неактивен

0    0    #25
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