SAMZ писал(а):Мне кажется, что здесь нет универсальных решений. Никаких циклов останавливать не надо.
Здравствуйте, как это не надо? Или я по ошибке FOR SELECT циклом называю? Тогда пардон. Ну все равно же это что-то типа перебора, да?
SAMZ писал(а):Тебе для себя надо решить, чего ты хочешь. Как можно понять из твоих писем, ты организуешь расчет по каким-то клинтам. Если для кокого-то клиента не хватает данных для корректного расчета (например, показаний счетчика) ну выведи в результатах по этому клиенту для этого расчета информацию (признак), предупреждающий о наступлении такого неприятного события. По этому признаку у клиента организуй предупреждение и интерфейс ввода доп.информациеи с пересчетом.
Р-р-р-р!!!

Товарищи дорогие! Да понимаю я постановку задачи. При наступлении в цикле (ну пусть не в цикле, а в FOR SELECT) события, при котором попадается услуга, требующая значения, на клиента надо отправить сигнал, чтобы он показал форму ввода этого значения. А потом забрать и продолжить расчет в этой же процедуре.
Ну как еще проще сказать!
Отопление значения не требует, т.к. площадь жилья не меняется раз в месяц., вода или канализация - тоже не требует, т.к. количество задниц - постоянная характеристика клиента (Условно). А вот
электроэнергия - от случая к случаю.
Мне не нужна постановка задачи, не блок-схема, это я понимаю. А вот живой кусок кода из процедуры не помешал бы.
Вот код процедуры расчета:
Код: Выделить всё
begin
/* № 0 */
execute procedure pr_add_n_family THMN_MID, D_BEG, D_FIN returning_values :opchelnum ; /*Получаем количество задниц за этот месяц*/
/* № 1 Delete if exists */
IF (EXISTS(SELECT MID, D_BEGIN, D_END FROM NACHISL
WHERE (MID = :THMN_MID AND D_BEGIN = :D_BEG AND D_END = :D_FIN ))) THEN
DELETE FROM NACHISL WHERE (MID = :THMN_MID AND D_BEGIN = :D_BEG AND D_END = :D_FIN ); /*Удаляем ранее посчитаные, если есть*/
/* № 3 Square & OSquare*/
SELECT THEMAIN.SQUARE, THEMAIN.OSQUARE FROM THEMAIN
WHERE THEMAIN.MID = :THMN_MID
INTO :opSQUARE, :opOSQUARE; /*Забираем площадь общую и отапливаемую из таблицы клиентов*/
/* № 4 Nachislenie*/
FOR SELECT MID, SRV_NAME, S_PRICE, NOT_SRVS, SPOS_NUM, TI_NAME /*[b]Вот про этот цикл я и говорил[/b]*/
FROM SERVICES /* эта таблица держит услуги по каждому клиенту, их тарифы, способы расчета, типы услуги, короче - у кого что есть */
WHERE (MID = :THMN_MID)
INTO :opMID, :opSRV_NAME, :opN_PRICE, :opNOT_SRVS, :opSPOS_NUM, :OPTI_NAME
DO
BEGIN
IF (:OPNOT_SRVS != 'Y' ) THEN
BEGIN /*ЕСЛИ НЕ СТОИТ ЧЕКА STOP*/
/*Вычисляем по тарифу и загоняем в переменную oppo_tarifu*/
execute procedure [b]pr_choos_sposob[/b] opspos_num, opchelnum, opn_price, opsquare, oposquare returning_values :oppo_tarifu;
/* Get next ID */
opNewID = GEN_ID(SCH_NACH, 1);
INSERT INTO NACHISL(
NID,
MID,
D_BEGIN, /*Дата начала месяца*/
D_END, /*Дата конца месяца*/
SRV_NAME, /*Наименование услуги*/
SPOS_NUM, /*Номер способа расчета - на каждый номер - свой способ*/
CHELNUM, /*Количество проживающих, т.е. задниц*/
SQUARE, /*Площадь - берем из таблицы клиентов*/
OSQUARE, /*Отаплив.площадь - оттуда же*/
[b] DEVICE, /*Вот он, этот чертов СЧЕТЧИК!!!*/[/b]
N_PRICE, /*Тариф*/
PO_TARIFU, /*Расчет по тарифу*/
DEVIACIA, /*Отклонение - если плохо отапливали или воды не было*/
PO_FAKTU, /*По_тарифу - Отклонение*/
LGOTA, /*Льгота*/
SUBSIDYA, /*Субсидия*/
K_OPLATE, /*Окончательно к оплате*/
PENI, /*Пени, ну это от случая к случаю*/
PAYMENT, /*Сколько оплачено*/
N_DATE, /*Дата начмсления*/
TI_NAME /*ЖКУ? Квартплата? Дополнительные услуги? Тип услуг*/
) VALUES (
:opNewID,
:opMID,
:D_BEG,
:D_FIN,
:opSRV_NAME,
:opSPOS_NUM,
:opCHELNUM,
:opSQUARE,/*from TheMain*/
:opOSQUARE,/*from TheMain*/
0,/*opDEVICE*/
:opN_PRICE,
:opPO_TARIFU,
0, /*opDEVIACIA*/
:opPO_TARIFU, /*opPO_FAKTU = opPO_TARIFU,*/
0, /*opLGOTA*/
0, /*opSUBSIDYA*/
0, /*opK_OPLATE*/
0, /*opPENI*/
0, /*opPAYMENT*/
'TODAY', /*opN_DATE*/ /*Тут еще Operator не забыть*/
:OPTI_NAME
);
END
END
SUSPEND;
END
Воот... Как видим, эта процедура верстает начисления по каждой услуге. Льготы, субсидии и пр. пока не готовы, но Po_Tarifu она уже высчитывает. Для этого она вызывает другую процедуру
pr_choos_sposob , которая и возвращает нужное значение.
Вот она:
Код: Выделить всё
begin
if (:inspos_num = 2) then /* Если 2 способ - по количеству проживающих - тариф умножить на людей*/
begin
execute procedure pr_sposob2 :inchelnum, :inprice returning_values :outpo_tarifu;
end
else if (:inspos_num = 3) then /* Если 3 способ - по отапливаемой площади - тариф умножить на площадь*/
begin
execute procedure pr_sposob3 :inosquare, :inprice returning_values :outpo_tarifu;
end
/********любой другой способ - все равно вручную, как и в способе №1 **********/
else
begin
execute procedure pr_sposob1 returning_values :outpo_tarifu;
end
suspend;
end
Во-о-о-от... Кстати, помните, я спрашивал, можно ли директиву Case использовать? Так вот - это для этой самой процедуры и было. Ну а маленькие процедуры расчета (pr_sposob1 , pr_sposob2) просто содержат в себе арифметику. В старой программе все это было в скриптах, которые пользователь мог менять... А то скажете - нагородил, блин! А тут - вот так приходится...
Так вот: если будет способ расчета 4 (по счетчику) - как из этих процедур вызвать его ввод и забрать. Вот чего я добиваюсь-то!
SAMZ писал(а):КАК это сделать - это твоя проблема. Никто за тебя это не решит.
Да. Если отправляют, то уж лучше так, чем прямо по матушке. Не так абыдна.
