Никак не пойму как такое сделать тут

Программирование на Атлантисе (VIP, FCOM, ARD), FastReport

Модераторы: m0p3e, edward_K, Модераторы

Optimist
Постоянный обитатель
Сообщения: 104
Зарегистрирован: 29 мар 2005, 17:49
Откуда: Moscow
Контактная информация:

Никак не пойму как такое сделать тут

Сообщение Optimist »

Привет рюхи!
Помогите кто знает.
Мне требуется восстановить таблицу иерархии контрагентов KontrIer по таблице KatOrgDescr.
Если у нас есть такая иерархия:

Все -> Покупатели -> ЧП Петя

то в KatOrgDescr содержатся записи:
ЧП Петя -> Покупатели
Покупатели -> Все

а в KontrIer:
ЧП Петя -> Покупатели
Покупатели -> Все
ЧП Петя -> Все

т.е. в KontrIer появляется дополнительная запись "ЧП Петя -> Все".
И я это пытаюсь реализовать при помощи следующего алгоритма:
Берем любую запись из KatOrgDescr, смотрим куда она ссылается и делаем ссылку (в KontrIer) на ту запись, потом смотрим куда ссылается та запись и делаем ссылку (опять же в KontrIer) на следующую и т.д., пока не будет достигнут "верхний уровень". Т.е. если я взял запись, содержащую "ЧП Петя", то я в KontrIer реализую ссылки "ЧП петя -> Покупатели" и "ЧП Петя -> Все".
Потом берем следующую запись из KatOrgDescr и снова пробегаем до верхнего уровня и так со всеми записями из KatOrgDescr.

Вот листинг программы (если что СОВСЕМ не так, то сильно не смейтесь - это мой первый ARD-отчет):

.FORM 'Восстановление KontrIer'
.ARD
.VAR
Gr:comp;
.ENDVAR

.CREATE VIEW ds
AS SELECT nrec,cgroup,isleaf,crec,name
FROM katorgdescr;

.{ // Начинается цикл LOOP
_LOOP ds
.BEGIN
Gr:= ds.katorgdescr.cgroup;
.END
.{
WHILE Gr <> 0000000000000000h
.INSERT kontrier
SET nrec = GetNextNRec(1472,0),
code = 0,
cgroup = Gr,
crecds = ds.katorgdescr.nrec,
name = ds.katorgdescr.name,
isleaf = ds.katorgdescr.isleaf;

Gr:= ????????????????

.}
.}
.endform

Теперь сам вопрос.
Мне надо чтоб переменная Gr "пробежала" по всем KatOrgDescr.cGroup до "верхнего уровня".

KatOrgDescr.cGroup == KatOrgDescr.NRec

Т.е. что-то типа этого (но это по-моему работать не будет):

Gr:= SELECT cgroup FROM ds.katorgdescr
WHERE Gr = ds.katorgdescr.nrec;

Надеюсь вы поняли мои объяснения что я хочу сделать. А как это сделать?
Спасибо.
Vitas
Местный житель
Сообщения: 230
Зарегистрирован: 29 мар 2005, 17:49
Откуда: Сибирь

Re: Никак не пойму как такое сделать тут

Сообщение Vitas »

тебе надо писать свою функцию, к.т. и будет все это дело раскручивать, лучше конечно на випе. Во-первых, зачем: INSERT kontrier
SET nrec = GetNextNRec(1472,0), зачем тебе вставлять нрек?
Во-вторых, зачем тебе crec?
В-третьих пиши на випе.
В-четвертых, на випе твоя структура:
Gr:= SELECT cgroup FROM ds.katorgdescr
WHERE Gr = ds.katorgdescr.nrec;
будет выглядеть как
if getfirst katorgdescr where ((gr=katorgdescr.nrec)) = tsOk gr:=katorgdescr.cgroup
или что-то в этом духе.
В любом случае лучьше писать на випе.
Ищу возможности довести и так отличный продукт до еще большего блеска
Optimist
Постоянный обитатель
Сообщения: 104
Зарегистрирован: 29 мар 2005, 17:49
Откуда: Moscow
Контактная информация:

Re: Никак не пойму как такое сделать тут

Сообщение Optimist »

4Vitas: Зачем мне вставлять нрек? Потому что я вставляю новую запись в таблицу и GetNextNRec мне нужен чтобы нрек был уникальным? Или я что-то не понимаю?

Сейчас у меня компиляция проходит нормально и вроде должна работать, но сразу после запуска галактика вылетает, причем видно что вслед за ней закрывается какое-то черное окно, но какая там ошибка прочитать не успеваю. Попробовал запустить галактику из cmd - тоже не получилось прочитать - она посмертное сообщение оставляет снова в своем быстрозакрывающемся окне.
Вот отчет, который я пытаюсь запустить. Что тут не так, ткните пожалуйста пальцем.

.FORM 'Восстановление KontrIer'
.ARD
.VAR
Gr:comp;
.ENDVAR

.CREATE VIEW ds
AS SELECT nrec,cgroup,isleaf,crec,name
FROM katorgdescr;

.{TABLE 'ds.katorgdescr:MAIN'
.BEGIN
Gr:= ds.katorgdescr.cgroup;

WHILE Gr <> 0000000000000000h DO BEGIN
INSERT kontrier
SET nrec = GetNextNRec(1472,0),
code = 0,
cgroup = Gr,
crecds = ds.katorgdescr.nrec,
name = ds.katorgdescr.name,
isleaf = ds.katorgdescr.isleaf;

IF getfirst katorgdescr WHERE ((gr==katorgdescr.nrec)) = tsOk
Gr:=katorgdescr.cgroup;

END;
END.
.}
.ENDFORM
andgott
Сообщения: 5
Зарегистрирован: 29 мар 2005, 17:49
Контактная информация:

Re: Никак не пойму как такое сделать тут

Сообщение andgott »

насчет nrec-a

попробуй вместо
SET nrec = GetNextNRec(1472,0),
написать
SET nrec = 0

по крайней мере в випе и паскале
при вставке новой записи пишут nrec:=0
а Галактика автоматом подставляет уникальный nrec
m0p3e
Местный житель
Сообщения: 1386
Зарегистрирован: 29 мар 2005, 17:49
Откуда: Москва

Re: Никак не пойму как такое сделать тут

Сообщение m0p3e »

Если существует корректный KatorgDescr, то функция проверки каталога контрагентов восстановит kontrier сама. По крайней мере в 5.82.
Optimist
Постоянный обитатель
Сообщения: 104
Зарегистрирован: 29 мар 2005, 17:49
Откуда: Moscow
Контактная информация:

Re: Никак не пойму как такое сделать тут

Сообщение Optimist »

Морзе, т.е. ты хочешь сказать что у меня и KatOrgDescr не корректный? Но ведь иерархическая структура сохранилась, только при выделении проблемы... Значит виноват KontrIer. Когда я провожу "проверку каталогов контрагентов", то восстанавливаются ссылки "ЧП Петя -> Покупатели" и "Покупатели -> Все", а "ЧП Петя -> Все" не восстанавливается. И у меня 5.82.

AndGott: "Ошибка №5. Дублированное значение при уникальном ключе." Но уже хоть не вылетает :)
Den
Местный житель
Сообщения: 1842
Зарегистрирован: 29 мар 2005, 17:49
Откуда: Ярославская область ОАО "Часовой завод Чайка" г. Углич
Контактная информация:

Re: Никак не пойму как такое сделать тут

Сообщение Den »

У меня тоже пару раз при выделении проблемы были, после проверки контрагентов все проблемы исчезали
sth
Постоянный обитатель
Сообщения: 148
Зарегистрирован: 29 мар 2005, 17:49

Re: Никак не пойму как такое сделать тут

Сообщение sth »

а так:

//SET nrec = GetNextNRec(1472,0)

// по идее nrec должен
//формироваться автоматически, или тебе
//зачем-то обязательно нужны строго
//последовательные nrecи?

ClearBuffer(#kontrier); // не факт что нужно
kontrier.code: = 0;
kontrier.cgroup: = Gr;
kontrier.crecds: = ds.katorgdescr.nrec;
kontrier.name: = ds.katorgdescr.name;
kontrier.isleaf: = ds.katorgdescr.isleaf;

INSERT current kontrier;
andgott
Сообщения: 5
Зарегистрирован: 29 мар 2005, 17:49
Контактная информация:

Re: Никак не пойму как такое сделать тут

Сообщение andgott »

Optimist:
вот видишь sth тоже говорит, что nrec автоматом формируется, а ошибка у тебя наверно вышла потому что была уже запись с чисто нулевым нреком. Можешь попробывать ее удалить и запустить еще раз.
В випе у тебя бы это точно прошло,
я похожие вещи делал на нем, не так уж там твой vip отличался бы от ard,
а чтоб не портить ресурсы скомпилил бы в debug и запустил как внешний интерфейс.
И ARD тогда не нужен.

На крайний случай - 100% средство:
сделал бы экспорт KatOrgDescr в dbf-ку, а по ней в любом языке программирования просчитал все что надо и закинул бы в dbf-ку со структурой аналогичной KontrIer (ее предварительно тоже для простоты и надежности можно експортом сделать),
а потом ее импортировал в галку.
По крайней мере всякий черных галковских окон уж точно не было бы.
Vitas
Местный житель
Сообщения: 230
Зарегистрирован: 29 мар 2005, 17:49
Откуда: Сибирь

Re: Никак не пойму как такое сделать тут

Сообщение Vitas »

Когда создавались таблицы в галке было у нрека при описании индексов что то типа:
ХХХХХХХХ0=nrec (Unique,Surrogate, Journal)
что все это значит я думаю и так ясно, поэтому нрек генерируется автоматически при вставке.
Ищу возможности довести и так отличный продукт до еще большего блеска
andgott
Сообщения: 5
Зарегистрирован: 29 мар 2005, 17:49
Контактная информация:

Re: Никак не пойму как такое сделать тут

Сообщение andgott »

Похоже все пытаются доказать Optimistu
что nreс формируется автоматом :-)))

Тогда он щас скорей всего спросит,
а зачем тогдаж функция GetNextNRec ? )))
sth
Постоянный обитатель
Сообщения: 148
Зарегистрирован: 29 мар 2005, 17:49

Re: Никак не пойму как такое сделать тут

Сообщение sth »

а getnextnrec для того, чтобы можно было, несмотря на randomsurrkeys в конфиге, получить последовательные значения nrecов если это зачем-то нужно твоему прикладному алгоритму :)))
Frodo
Посетитель
Сообщения: 37
Зарегистрирован: 29 мар 2005, 17:49

Re: Никак не пойму как такое сделать тут

Сообщение Frodo »

На мой взгляд обсуждение механизма генерации nRec - это повод для открытия новой темы в форуме. Но поскольку нас занесло сюда:
Функция GetNextNrec и команда Insert дают разные результаты при условии, что DataBase.RundomSurrKeys = on. Тест:

insert to tabl set nrec := comp(0), name := 'Вася';
и кажущийся эквивалент
insert to tabl set nrec := GetNextNrec(tabl), name := 'Вася';

В первом случае nrec сформирован через таблицу суррогатных ключей. Во втором я пока не знаю (кто знает отзовись), но думаю что через какую-то переменную формируемую при старте пользователя и МАС-адрес.
В случае если DataBase.RundomSurrKeys = off обе команды дадут одинаковый результат.

И в заключение из собственного опыта: Функция GetNextNrec может и дает сбои, что зафиксированно на нашей БД (ver.5.74 Pervasive 2000i SP2, размер ~40Гб, 50 активных пользователей) в интерфейсе групповой разноски платежей.
Vitas
Местный житель
Сообщения: 230
Зарегистрирован: 29 мар 2005, 17:49
Откуда: Сибирь

Re: Никак не пойму как такое сделать тут

Сообщение Vitas »

А так не пробовал?:
insert to tabl set name := 'Вася';
Ищу возможности довести и так отличный продукт до еще большего блеска
Optimist
Постоянный обитатель
Сообщения: 104
Зарегистрирован: 29 мар 2005, 17:49
Откуда: Moscow
Контактная информация:

Re: Никак не пойму как такое сделать тут

Сообщение Optimist »

SET nrec = 0
вполне работает, спасибо
Ошибка была из-за того, что индекс KONTRIER02 должен быть уникальным (он висит на полях cgroup, crecds), а у меня какая-то ошибка в алгоритме... Почему-то...
Ответить