似乎NAV的潜在本质是抵制要求填充字段是强制性的.在我们的业务逻辑的情况下,必须填充某些字段以使数据有效.例如,客户记录必须至少包含姓名和电话号码.我搜索了很多地方,但没有找到合适的解决方案.那怎么能实现呢?
在努力寻找一种简洁的方法来要求填充卡上的某些字段之后,我想出了以下方法,并且它(到目前为止)对我有用。我开始意识到 NAV 并不意味着有必填字段,但我需要它们来实现我们的业务逻辑。无论如何,我们来了...
第一步: - 我们有一个用于各种验证逻辑的代码单元,其中我添加了读取自定义表的函数,其中列出了表及其强制字段。该函数采用表号、关键字段和“创建模式”。它返回一个文本“完成状态”值。我找到了我正在验证的记录表。我循环遍历必填字段,如果该字段未填充,我会将其添加到不完整字段列表中。如果不完整字段列表为空,则完成状态为“完成”。如果填充了不完整字段的列表,则会显示一条消息,指示缺失的字段,并允许用户选择取消创建新记录或保留(新的或现有的)记录并输入缺失的数据,并且完成状态设置为“删除”以取消创建,或“返回”以保留在记录中。逻辑如下:
CheckMadatoryFields(TableNumber : Integer;KeyField : Code[10];CreateMode : Boolean) Completion Status : Text[30]
// Read the 'LockoutFields' table to find the manditory fields for the table passed in.
LockoutFields.RESET;
LockoutFields.SETRANGE("Table No.", TableNumber);
LockoutFields.SETFILTER("Filter ID", 'MANDITORY_FIELD');
// Get a record reference for the table passed in
RecRef.OPEN(TableNumber);
RecRef.SETVIEW('WHERE("No." = FILTER(' + KeyField + '))');
// Set this to done, i.e. data is complete (don't delete by mistake).
CompletionStatus := 'done';
IF RecRef.FINDFIRST THEN BEGIN
// Check the record's manditory field(s) listed in the 'LockoutFields' table to see if they're blank.
IF LockoutFields.FINDSET THEN BEGIN
REPEAT
FldRef := RecRef.FIELD(LockoutFields."Field No.");
IF FORMAT(FldRef.VALUE) = '' THEN
FldList := FldList + ' - ' + FldRef.CAPTION + '\';
UNTIL LockoutFields.NEXT = 0;
END;
IF FldList <> '' THEN BEGIN
// If creating the record, add the 'Cancel Create' message, otherwise don't.
IF CreateMode THEN
DeleteRecord := CONFIRM(Text_ManditoryField + '\' + FldList + '\' + Text_CancelCreate, FALSE)
ELSE BEGIN
DeleteRecord := FALSE;
MESSAGE(Text_ManditoryField + '\' + FldList, FALSE);
END;
// Return a 'delete' status when deleting, or a 'return' status to stay on the record.
IF DeleteRecord THEN
CompletionStatus := 'delete'
ELSE
CompletionStatus := 'return';
END;
END;
RecRef.CLOSE;`
Run Code Online (Sandbox Code Playgroud)
步骤 2: - 在您想要检查必填字段的卡上,在我的例子中是客户卡,我添加了一个函数来调用上述代码单元中的验证函数。我还向 OnQueryClosePage 触发器添加了逻辑以调用我的本地函数。这一切都运行良好,因为用户在未完成必填字段或取消客户创建的情况下无法关闭客户卡,除非用户使用 Ctrl+PgUp 或 Ctrl+PgDn(这会将其从记录中删除)。诀窍是将正确的逻辑放入 OnNextRecord 触发器中,以便执行验证并且 Ctrl+PgUp 或 Ctrl+PgDn 仍然起作用(注意:我在 mibuso 上的某个地方找到了这一点,非常感谢!)。逻辑如下:
OnNextRecord(...)
IF CheckManditoryFields = TRUE THEN BEGIN
Customer := Rec;
CurrentSteps := Customer.NEXT(Steps);
IF CurrentSteps <> 0 THEN
Rec := Customer;
EXIT(CurrentSteps);
END;
OnQueryClosePage(...)
EXIT(CheckManditoryFields);
CheckMandatoryFields() ExitValue : Boolean
// Check for manditory fields on this table. If there are missing manditory
// fields, the user can cancel this create, in which case, a 'TRUE' value is
// returned and we'll delete this record.
ExitValue := TRUE;
IF Rec."No." <> '' THEN BEGIN // This is blank if user quits immediately after page starts.
CompletionStatus := HHValidation.CheckManditoryFields(18,Rec."No.",CreateMode);
IF (CompletionStatus = 'delete')
AND (CreateMode = TRUE) THEN // User cancelled create (not edit), delete the record and exit.
Rec.DELETE(TRUE)
ELSE
IF CompletionStatus = 'done' THEN // User completed manditory fields, OK to exit.
ExitValue := TRUE
ELSE
ExitValue := FALSE; //User did not complete manditory fields and wants to return and add them.
END;
Run Code Online (Sandbox Code Playgroud)
我想就是这样。自定义表的详细信息实际上取决于您想要如何编码。验证码单元可以是您想要的。使用表格可以在不更改任何逻辑的情况下添加或删除必填字段,并且可以将这种“通用”验证逻辑放在任何页面上。关键是卡上的两个触发器以及调用的通用验证例程。