Форма на основе параметрического LocalView

miv32
Дата: 28.08.2012 15:53:23
Добрый день!
Как обновить данные в форме, если они берутся из параметрического view при добавлении новой записи?

В Ините формы:

*********
PARAMETERS id_code - Ключевое поле таблицы "contract" (contract_id)
THISFORM.id_code = id_code (при добавлении = 0)

lnContractId = THISFORM.id_code
где lnContractId - параметр вьюхи, которая лежит в Dataenvironment с параметром NoDataOnLoad = .T.

Requery("v_contract")
=CURSORSETPROP("Buffering", 5, "v_contract")

IF THISFORM.id_code = 0
select v_contract
APPEND BLANK
ENDIF
************
В default value таблицы contract стоит функция получения нового значения ключа.
Данные по TableUpdate() благополучно попадают в исходную таблицу.

Повторная выдача Requery("v_contract") ничего не дает, т.к. вьюха о новом значении ничего не знает.
Как быть?
ВладимирМ
Дата: 28.08.2012 17:53:59
Добавление записи во View еще не означает добавление записи в таблицу-источник. Т.е. команда APPEND BLANK создала запись в буфере View, но еще ничего не создала в таблице-источнике. Чтобы запись физически создалась в таблице-источнике необходимо сбросить буфер. Т.е. дать команду TableUpdate()

Если у Вас используется функция для генерации идентификатора записи, то кто мешает вызвать эту функцию "вручную" и присвоить значение полю ID во View?

IF THISFORM.id_code = 0
    select v_contract
    APPEND BLANK
    replace id_code with MyFunc()
ENDIF


Разумеется, пометив поле id_code как обновляемое. Тогда после команды TableUpdate(), поскольку поле не пустое, будет просто записано сформированное значение. Default Value вызываться не будет.
miv32
Дата: 28.08.2012 20:56:54
Спасибо,так и сделал. Но пришлось оборачивать в транзакцию для, если что, отката данных в табличке, где храняться последние значения ключевых полей.

LOCAL llSuccess,laError(1),lnNewRecContractId
llSuccess = .T.

BEGIN TRANSACTION
THISFORM.id_code = AddNewRecord("contract")

SELECT v_contract
replace contract_id WITH THISFORM.id_code

m.llSuccess = TableUpdate(.T.,.T.,"v_contract")

IF m.llSuccess = .T.
END TRANSACTION
ELSE
ROLLBACK
=AERROR(laError)
*Дальше анализ ошибки и вывод MESSAGEBOX*
ENDIF

Ну и lnContractId = THISFORM.id_code
Requery("v_contract")
ВладимирМ
Дата: 29.08.2012 00:00:58
Неправильно сделали. По сути, Вы физически создаете новую запись каждый раз при открытии формы без возможности отменить это создание. А если пользователь открыл форму, подумал, и решил не создавать запись? А Вы ее уже физически создали и откатить ничего невозможно!

Надо было формировать код записи именно во View, а не в таблице-источнике. Другими словами, Вам вполне достаточно было сделать

* Init - формы

PARAMETERS id_code - Ключевое поле таблицы "contract" (contract_id)
THISFORM.id_code = id_code (при добавлении = 0)

lnContractId = THISFORM.id_code

Requery("v_contract")
=CURSORSETPROP("Buffering", 5, "v_contract")

IF THISFORM.id_code = 0
     THISFORM.id_code = AddNewRecord("contract")
     select v_contract
     APPEND BLANK
     replace contract_id WITH THISFORM.id_code
ENDIF


Ну, а команду TableUpdate() давать как и положено, по нажатию кнопки "Сохранить" на форме. Только, еще раз повторюсь, надо в дизайнере View сделать поле contract_id обновляемым, поскольку по умолчанию, ключевые поля не помечаются как обновляемые.

PS: Если Вы таким образом пытаетесь бороться с "дырами" в нумерации, то, во-первых, это в большинстве случаев абсолютно бессмысленное занятие. Ведь записи могут быть удалены, что автоматически означает "дыру" в нумерации. Вас же эта "дыра" не волнует, так чего же беспокоится о "дырах" при создании новой записи? А, во-вторых, если все-таки это имеет принципиальное значение, то ТАК это не делается. Все организуется несколько более сложным способом через дополнительные списки "дыр".
miv32
Дата: 29.08.2012 01:32:21
Сорри, это не в Ините формы! Я забыл комменты вставить. Ночь, однако!
Собственно задачка в редактировании формы с данными один ко многим.
Т.е. шапка + спецификация в виде грида. Связка идет по полю contract_id

Получился вот такой рабочий полуфабрикат.

PARAMETERS id_code
THISFORM.id_code = id_code

THISFORM.grdDisloc.RecordSource = ""

LOCAL lnContractId
m.lnContractId = THISFORM.id_code

Requery("v_contr_cust")
Requery("v_disloc_address")

=CURSORSETPROP("Buffering", 5, "v_contr_cust") - шапка(одна строка)
=CURSORSETPROP("Buffering", 5, "v_disloc_address") - спецификация(много)

THISFORM.grdDisloc.RecordSourceType = 1
THISFORM.grdDisloc.RecordSource = "v_disloc_address"

IF THISFORM.id_code = 0
APPEND BLANK
ENDIF

В ините все, не считая кое-каких мелочей по установке значений по умолчанию в шапке.

Теперь сохранение. (опять же надо причесать)

LOCAL llSuccess,lnNewRecContractId,lnNewDislocId
llSuccess = .T.
BEGIN TRANSACTION

IF THISFORM.id_code = 0
*Новая запись*
THISFORM.id_code = AddNewRecord("contract")

SELECT v_contr_cust
replace contract_id WITH THISFORM.id_code
ENDIF

m.llSuccess = TableUpdate(.T.,.T.,"v_contr_cust")
IF m.llSuccess = .T.
*Если в шапке все в порядке, идем по строкам в спецификации*
SELECT v_disloc_address
IF GETNEXTMODIFIED(0,"v_disloc_address") <> 0
GO TOP
nRec=GETNEXTMODIFIED(0,"v_disloc_address")
DO WHILE nRec!=0
GO nRec
IF nRec < 0
*Новая*
lnNewDislocId = AddNewRecord("disloc")
SELECT v_disloc_address
*Занесение ключевых полей*
replace disloc_id WITH lnNewDislocId,contract_id WITH THISFORM.id_code
ENDIF

m.llSuccess = TableUpdate(0,.T.,"v_disloc_address")
IF m.llSuccess = .F.
EXIT
ENDIF
nRec=GETNEXTMODIFIED(nRec)
ENDDO
ENDIF
ENDIF

IF m.llSuccess = .T.
END TRANSACTION
ELSE
ROLLBACK
ENDIF

m.lnContractId = THISFORM.id_code

Requery("v_contr_cust")
Requery("v_disloc_address")
thisform.Refresh

Галочки везде где положено стоят, все работает.

Вот как-то так, и никаких дыр. Другое дело, что пока будет все это хозяйство заполняться транзакция будет висеть. Но в моем случае спецификация насчитывает не так много строк.
Что посоветуете? Я раньше с фоксовыми вьюхами не работал, какое-то недоверие к ним. Да и пока эти тестил, фокс успел докатиться при Requery() до "серьезного сбоя" так, что комп ребутить пришлось. Руки кривые может...
Jonny540
Дата: 29.08.2012 07:55:14
miv32,

Как-то все у вас сложно :) Положите на форму кнопки "новый" и "изменить".
По "новый" вы заводите новую запись в родительской таблице и (если надо), то и в дочерней.
По "изменить" - только изменения в дочерней. Для получения новых ид можно сделать две рабочие таблицы с доступными ид.
Автоматизация, конечно, дело хорошее, но не да такой степени.
То, что я сейчас написал, успешно работает уже ...цтать лет. Если есть вопросы - пишите.
miv32
Дата: 29.08.2012 10:03:55
И родительская и доченяя могут меняться.
Классический пример - приходная накладная.
В шапке - номер,поставщик,дата, и пр.вещи.
В спецификации - перечень товаров с количеством и ценой,кол-во уже списанного.
Надо иметь возможность править и шапку и спецификацию(грид).

Класть на каждую форму кнопки добавить-изменить считаю дурным тоном. :)
В тулбаре программы одна кнопка для добавить,одна изменить для всех форм.

В форме для редактирования под спецификацией две - (+) (-). Или по правому щелчку на спецификации они же дублируются в контекстном меню.
Jonny540
Дата: 29.08.2012 12:12:40
miv32
Класть на каждую форму кнопки добавить-изменить считаю дурным тоном. :)
А где тут дурной тон? "не, вы только посмотрите, вся Одесса не считает, а он считает"(с)
miv32
В тулбаре программы одна кнопка для добавить,одна изменить для всех форм.

В форме для редактирования под спецификацией две - (+) (-). Или по правому щелчку на спецификации они же дублируются в контекстном меню.
Ну-ну... Каждый сходит с ума по-своему...
Станислав С...кий
Дата: 02.09.2012 00:43:01
miv32,

Не знаю, зачем Вы так сложно сделали. У нас в учетной системе сделано немного по-другому:
Форма 1: список накладных (шапки). Если хотите, то можно в форму 1 добавить грид (без возможности редактирования, только для информации) для отображения строк спецификации текущей накладной.
По кнопке "редактировать" данные "шапки" накладной можно редактировать в форме редактирования и там же сохранить изменения или откатить их. По нажатию другой кнопки - переход в форму 2, третья - печать необходимых отчетов...
Форма 2: строки спецификации текущей накладной. В верхней части формы - повторение информации "шапки" спецификации. По нажатию кнопки "редактировать" происходит редактирование текущей строки спецификации. На форме также присутствуют кнопки "добавить", "удалить", "сохранить", "отмена".

Еще никто не жаловался на работу этой схемы, которую мы (возможно, не только мы) обобщенно называем "регистрация - спецификация"...
miv32
Дата: 03.09.2012 19:27:24
Спасибо, :) Придется мудрить...