powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Заполнение курсора из другого курсора
15 сообщений из 15, страница 1 из 1
Заполнение курсора из другого курсора
    #37465414
Allkay
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В курсоре t1_al имеются поля dnei, dn_per, op_pozakr.
Dnei – количество дней опозданий по переносу карточки и + по закрытию.
dn_per – количество дней опозданий по переносу.
op_pozakr - количество дней опозданий по закрытию.

Все поля необходимые для заполнения курсора t1_al, заполняются в курсоре perenosy
(поля в курсоре sum_per, sum_op_zakr, sum_nn)

Вопрос: Как данные из курсора perenosy записать в курсор t1_al
...
Рейтинг: 0 / 0
Заполнение курсора из другого курсора
    #37465453
Allkay
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Allkay,

Кто будет участвовать огромное спасибо.
...
Рейтинг: 0 / 0
Заполнение курсора из другого курсора
    #37466443
Allkay,
есть два пути:
1. Если необходимые данные есть в курсоре perenosy, то пишешь:
Код: plaintext
 select <Нужные поля> from perenosy into cursor t1_al where <условия отбора данных>
2. Если необходимых данных нет и их надо готовить специальным образом, то пишешь:
create cursor t1_al (dnei N(3,0), dn_per N(3,0), op_pozakr N(3,0))
<здесь готовятся необходимые данные>
insert into t1_al values (...., ...., ....)
...
Рейтинг: 0 / 0
Заполнение курсора из другого курсора
    #37467066
Allkay
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как заполнить курсор, в принципе понятно, проблема в том, как сохранить данные, (Извлечь данные подсчета) из алгоритма подсчета. Ведь те данные, что мне нужны, существуют на этапе подсчета в алгоритме (Алгоритм подсчета дней) после окончания подсчета их нет (если остается то только последняя запись).
Для заполнения курсора t1_al, нужно, на этапе подсчета в курсоре perenosy, запоминать данные, чтобы по окончании подсчета из памяти заполнить t1_al.
...
Рейтинг: 0 / 0
Заполнение курсора из другого курсора
    #37467328
Allkay
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БД
...
Рейтинг: 0 / 0
Заполнение курсора из другого курсора
    #37467587
SSn888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Allkay,

данные в курсоре _никогда_ сами собой не сохранятся
он живет только пока не закончиться сеанс работы либо Вы его не убъете явно внутри алгоритма
курсор _по_определению_ - временная штука
если Вам надо именно хранить информацию - либо пользуйтесь таблицами сразу либо в нужный момент скидывайте все из курсора в таблицу

sele * from курсор into table таблица

как вариант - скидывайте из курсора в уже имеющуюся таблицу данные периодически

insert into таблица sele * from курсор where условиеотборанужныхстрок
...
Рейтинг: 0 / 0
Заполнение курсора из другого курсора
    #37468438
Allkay
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть еще какие ни будь варианты?
...
Рейтинг: 0 / 0
Заполнение курсора из другого курсора
    #37469233
SSn888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Allkay,

Да, есть другие варианты
Нарисовать алгоритм карандашом на бумаге, его обдумать, еще раз обдумать - уже тщательно. Переделать с нуля всю логику проги и структуру БД.
Потому что даже начало
"Dnei – количество дней опозданий по переносу карточки и + по закрытию.
dn_per – количество дней опозданий по переносу."
говорит о том, что и программа, и база у Вас скоро будут представлять собой "Тришкин кафтан" - объем заплаток и доковырок превысит объем собственно самой работы.
Уж не знаю - зачем это все держать в курсорах, кстати, и как Вы в таких случаях обходите коллизии, но советую начать хотя бы с
"Dn_zak – количество дней по закрытию.
dn_per – количество дней опозданий по переносу.", а финты типа "поле равно другое поле плюс икс" - позабыть как можно скорей...
...
Рейтинг: 0 / 0
Заполнение курсора из другого курсора
    #37470395
Allkay
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SSn888,

Выход, я, кажется, нашел, и как не странно с помощью курсора.
Создал в начале алгоритма подсчета дней, курсор, затем в процессе подсчета количества дней заполнял новый курсор. На выходе получилось, мне нужный курсор t1_al, для заполнения отчета, и новый курсор заполненный данными. Осталось только заполнить курсор t1_al из нового курсора.
А что плохого в ворожении: поле = поле + х ?
...
Рейтинг: 0 / 0
Заполнение курсора из другого курсора
    #37470400
Allkay
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Примерно ток.
...
Рейтинг: 0 / 0
Заполнение курсора из другого курсора
    #37473680
SSn888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Allkay,

извините, только ща нормально добрался до компа
на выходных отвечу
...
Рейтинг: 0 / 0
Заполнение курсора из другого курсора
    #37474133
reware
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AllkayКак заполнить курсор, в принципе понятно, проблема в том, как сохранить данные
Сохраняйте INTO TABLE или INTO ARRAY либо селектом, либо по мере их вычисления процедурно (REPLACE TempTable.pole1 WITH a1 или TempArray[1]=a1).
...
Рейтинг: 0 / 0
Заполнение курсора из другого курсора
    #37482300
SSn888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Allkay

Хотел просто прислать Вам слегка измененный Ваш ше текст, но споткнулся о то, что не совсем уверен в своем понимании смысла полей :)

Почему отпишу тут... Просьба не воспринимать как критику вроде "почему без шапки" :)

0) "А что плохого в ворожении: поле = поле + х ?"
Почитайте про нормализацию

1) В фоксе есть возможность переноса части строки по желанию, табы и прочее. Пользуйтесь все-таки этим для того, чтоб текст не представлял собой кашу, так и Вам самому будет удобней... например, сравните

SELECT Pointtask.regnumb, Pointtask.pointnumb, Pointtask.pointsod, Pointtask.dateout, ;
{..} as datenew, Pointtask.datefact, Pointtask.datecansel, Pointtask.datemarke, ;

и

SELECT PointTask.pointNumb,;
PointTask.pointSod,;
PointTask.dateOut,;
PointTask.dateFact,;
PointTask.dateCansel,;
PointTask.dateMarke,;
IIF(EMPTY(PointTask.dateNew),;
PointTask.dateOut,;
PointTask.dateNew) AS d_n, ;
IIF(EMPTY(PointTask.dateFact) OR PointTask.dateFact>datt_ok,;
datt_ok,
PointTask.dateMarke) AS d_mkk,;
PointTask.tabMark,;
PointTask.tabReg;
FROM PointTask;
WHERE (PointTask.regNumb == lcRegNumb);
INTO CURSOR crsPointTask;
ORDER BY pointSod

2) Если посмотреть на содержимое полей в первом Вашем запросе и их наличию в объединяемых таблицах - то приходит мысль, что UNION тут как раз не совсем нужен, лучше как-то обыграть JOIN, нет нужды городить "шахматку"

3) Формула nn = t1_al.d_mkk - (t1_al.d_n) реально работает только для PointTask, давая
nn = IIF(EMPTY(PointTask.datefact) OR PointTask.datefact>datt_ok,;
datt_ok,;
PointTask.datemarke) -;
IIF(EMPTY(PointTask.datenew),;
PointTask.dateout,;
PointTask.datenew)
Для PointMove в любом раскладе будет nn = {..} - {..}
Причем данные зависят только от инфы в курсоре, никаких "внешних влияний" нет
Тогда зачем это все считать в скане, а не просто вынести в первый запрос как вычисляемое поле?

4) Поле regn, формрируемое по принципу
(ALLTRIM(pointtask.regnumb)+'('+ALLTRIM(pointtask.pointnumb)+')')
и далее по той же логике используемое для сравнения - абсолютно излишне, бо часть regnumb его вообще-то выходит константой, для сравнения и прочего вполне достаточно pointnumb
(В самом начале указывается
lcRegNumb ='21066001'
и курсор формируется с WHERE PointTask.regnumb = lcRegNumb...
то есть - по логике - в дальнейшей части блока поле regnumb вообще не нужно как факт)

5) Селект внутри цикла в этой ситуации... эээ... во-первых - слишком неизящно, во-вторых - может довести до безобразия.
На каждую запись курсора1 (сформированного из 2 источников) приходится обработка всех записей курсора2... как - нет торможения проги даже на тесте?
Как понимаю - этот хитрый путь возник из суровой необходимости - ведь надо брать данные dat_perper для следующей записи из предыдущей. В запросе это сразу написать - легче застрелиться.
Есть способ "объехать на кривой козе", устроив самообъединение со сдвигом
1. Добавляем столбец-нумератор
ну, например,
SELECT *, recno() AS rcn
FROM ....
2. Делаем копию результата (на самом деле - это все можно сделать и без копии, слегка укрупнив запрос, но грузить не буду)
SELE * FROM A1 TO A2
3. Сливаем
SELECT A1.datenew AS d_n1,;
A1.. ...
A2.datenew AS d_n2; && то, что ранее пихал в dat_perper в цикле
FROM A1;
LEFT JOIN A2;
ON (A1.rcn +1 == A2.rcn )
INTO.....
4. Выкидываем то, что уже "отработано" - убиваем курсоры A1 & A2
5. Всю алгебру/геометрию из цикла переносим в запрос как вычисляемые поля

6) Собственно - если у Вас результат всей этой обработки идет _только_ в отчет - нет нужды в половине всей этой обработки
Подсчет количеств и прочее удобней реализовать внутри самого отчета
В меню report зайти в variables, добавить переменную, выбрать нужный calculationtype и так далее...
в отчете просто добавить объект поле с этой переменной
...
Рейтинг: 0 / 0
Заполнение курсора из другого курсора
    #37491713
Allkay
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SSn888,

SSn888 Спасибо за помощь, я как говорил нашел выход и поэтому не проверял форум.
А ответ вот какой он:

*Выбор исходных данных (Основной курсор)
SELECT Pointtask.pointnumb, Pointtask.pointsod, Pointtask.dateout, ;
{..} as datenew, Pointtask.datefact, Pointtask.datecansel, Pointtask.datemarke, ;
000000 as dnei, 000000 as dn_per, 000000 as op_pozakr, ;
(ALLTRIM(pointtask.regnumb)+'('+ALLTRIM(pointtask.pointnumb)+')') as regn, ;
IIF(EMPTY(pointtask.datenew), pointtask.dateout, pointtask.datenew) as d_n, ;
IIF(EMPTY(pointtask.datefact) OR pointtask.datefact>datt_ok, datt_ok, pointtask.datemarke) as d_mkk, ;
Ispleader.fio as fiomark, Abonent.fio as fioreg ;
FROM bduaski!Pointtask ;
LEFT OUTER JOIN bduaski!ispleader ;
ON Pointtask.tabmark = Ispleader.tabel ;
LEFT OUTER JOIN bduaski!abonent ;
ON Pointtask.tabreg = Abonent.tabel ;
WHERE Pointtask.regnumb = lcRegNumb ;
UNION ;
SELECT Pointmove.pointnumb, " " as pointsod, {^2199.12.31} as dateout,;
Pointmove.datenew, {..} as datefact, {..} as datecansel, Pointmove.datemarke, ;
000000 as dnei, 000000 as dn_per, 000000 as op_pozakr, ;
" " as regn, {..} as d_n, {..} as d_mkk, ;
Ispleader.fio as fiomark, Abonent.fio as fioreg ;
FROM bduaski!Pointmove ;
LEFT OUTER JOIN bduaski!ispleader ;
ON Pointmove.tabmark = Ispleader.tabel ;
LEFT OUTER JOIN bduaski!abonent ;
ON Pointmove.tabreg = Abonent.tabel ;
WHERE Pointmove.regnumb = lcRegNumb ;
ORDER BY 1,3 INTO CURSOR t1_al READWRITE

*Создание курсора
CREATE CURSOR pointtask2 (pointnumb C(9), datenew D(8), datemarke D(8), kol_dn_op N(10), kol_dn_oprab N(10), sum_kol_dn_oprab N(10))
*Алгоритм подсчёта дней
SELECT t1_al
SCAN
*Селект собирающий все переносы по текущей карте
SELECT pointmove.pointnumb, pointmove.datenew, pointmove.datemarke, 000000 as kol_dn_op, 000000 as kol_dn_oprab, 000000 as sum_kol_dn_oprab ;
FROM pointmove WHERE ALLTRIM(pointmove.regnumb)+'('+ALLTRIM(pointmove.pointnumb)+')'=t1_al.regn INTO CURSOR perenosy READWRITE ORDER BY 1,3

SELECT perenosy
GO TOP
*Подсчёт общего числа переносов
kol_per=RECCOUNT()
*Подсчёт Опоздания по переносам
op_per=0
*Подсчёт Опоздания по закрытию, или не закрыта а должна
op_zakr=0
*Если есть переносы, выполняется:
IF kol_per>0
*Запоминаем дату када должен был быть первый перенос (дата первого переноса это -- дата выполнения)
dat_perper = t1_al.dateout
FOR i=1 TO kol_per
*Если есть опоздания, т.е. дата выполнения меньше даты отметки (SKIP 1)
IF dat_perper < perenosy.datemarke
*Считаем кол-во дней опоздания
nn = perenosy.datemarke - (dat_perper)
REPLACE perenosy.kol_dn_op WITH nn
*Выключен подсчёт рабочих дней
nn = nn-3
*Если nn < 0 значит опозданий нет
IF nn < 0
nn = 0
ENDIF
*Проссумировали дни опоздания
op_per = op_per + nn
REPLACE perenosy.kol_dn_oprab WITH nn
REPLACE perenosy.sum_kol_dn_oprab WITH op_per

*Заполнение курсора данными из другого курсора
*SELECT perenosy
*GO TOP
*IF !EOF()
INSERT INTO Pointtask2 (pointnumb, datenew, datemarke, kol_dn_op, kol_dn_oprab, sum_kol_dn_oprab);
VALUES (perenosy.pointnumb, perenosy.datenew, perenosy.datemarke, perenosy.kol_dn_op, perenosy.kol_dn_oprab, perenosy.sum_kol_dn_oprab)
*ENDIF
ENDIF
*Присвоение (следующего) начального значения для даты переноса
dat_perper = perenosy.datenew
*Перемещаемся на след по времени перенос
SKIP
*Выход из цикла если больше нет переносов
ENDFOR
ENDIF
*Были или нет переносы,считаем колво дней опозданий с даты начала подсчёта(dateout или datenew <соответствует последнему переносу>)
nn = t1_al.d_mkk - (t1_al.d_n)
nn = nn - 3
IF nn < 0
nn = 0
ENDIF
op_zakr = op_zakr + nn
*Заполняем главную таблицу
SELECT t1_al
*Заносим подсчитанные дни опоздания ( t1_al -- заполняется во время выполнения цикла )
REPLACE t1_al.dnei WITH op_per + op_zakr, t1_al.dn_per WITH op_per, t1_al.op_pozakr WITH nn
ENDSCAN

*Заполнение курсора t1_al курсором Pointtask2*
SELECT t1_al.pointnumb, t1_al.pointsod, t1_al.dateout, ;
t1_al.datenew, t1_al.datefact, t1_al.datecansel, t1_al.datemarke, ;
t1_al.dnei, t1_al.dn_per, t1_al.op_pozakr, ;
t1_al.fiomark, t1_al.fioreg, ;
Pointtask2.kol_dn_op, Pointtask2.kol_dn_oprab, Pointtask2.sum_kol_dn_oprab ;
FROM t1_al ;
LEFT OUTER JOIN Pointtask2 ;
ON t1_al.pointnumb=Pointtask2.pointnumb AND t1_al.datenew=Pointtask2.datenew ;
ORDER BY 1,3 INTO CURSOR expPoint READWRITE

*Последний селект для заполнения отчета*
SELECT expPoint.pointnumb, expPoint.pointsod, ;
IIF(expPoint.dateout={^2199.12.31},{..},expPoint.dateout) as dateout, ;
expPoint.datenew, expPoint.datefact, expPoint.datecansel, expPoint.datemarke, ;
expPoint.dnei,;
IIF(expPoint.dn_per<expPoint.kol_dn_oprab, expPoint.kol_dn_oprab, expPoint.dn_per) as dn_per, ;
expPoint.op_pozakr, ;
expPoint.fiomark, expPoint.fioreg ;
FROM expPoint ;
INTO CURSOR expert READWRITE
...
Рейтинг: 0 / 0
Заполнение курсора из другого курсора
    #37491799
Allkay
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Заполнение курсора из другого курсора
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]