Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用DBLookupComboBox选择外键值而不立即更改目标表?(Delphi 5 Pro)_Delphi_Combobox_Foreign Keys_Delphi 5 - Fatal编程技术网

如何使用DBLookupComboBox选择外键值而不立即更改目标表?(Delphi 5 Pro)

如何使用DBLookupComboBox选择外键值而不立即更改目标表?(Delphi 5 Pro),delphi,combobox,foreign-keys,delphi-5,Delphi,Combobox,Foreign Keys,Delphi 5,基本情景: 用户单击“编辑项目” “编辑”对话框打开 组合框“项目类型”应填充表格“项目类型”中的项目。组合框应显示“item\u type.name”,但也应知道“item\u type.id” 用户编辑其他项目内容并选择项目类型,然后单击“确定” 我的程序做一些输入验证 如果一切正常,从所选组合项中获取“item_type.id”,并将其保存到item表的外键列(“item.fk_item_type”) 如果我正确理解这个组件,我应该将DataSource设置为指向目标表“item”,将Da

基本情景:

  • 用户单击“编辑项目”
  • “编辑”对话框打开
  • 组合框“项目类型”应填充表格“项目类型”中的项目。组合框应显示“item\u type.name”,但也应知道“item\u type.id”
  • 用户编辑其他项目内容并选择项目类型,然后单击“确定”
  • 我的程序做一些输入验证
  • 如果一切正常,从所选组合项中获取“item_type.id”,并将其保存到item表的外键列(“item.fk_item_type”)
  • 如果我正确理解这个组件,我应该将DataSource设置为指向目标表“item”,将DataField设置为“item.fk_item_type”。但这会在我有机会验证所有其他输入之前立即编辑我的项目表

    我觉得我错过了什么。我在某个地方读到,我需要使用一个经典的组合框并手动填充它。但是我不知道如何获取所选项目的id

    谢谢你的指点

    编辑:
    我开始怀疑也许我错过了一件基本的事情。所有这些DB*组件,它们是否自动从数据库加载值,但我必须自己调用Post()?这意味着它们不会自动更改数据库中的值?

    如果我理解正确,您希望使用DBLookupComboBox。必须为以下属性提供值

    • 数据源-链接到您正在编辑的表,可能是“项”
    • datafield—您正在编辑的表中字段的名称,可能是“item\u type”
    • listsource-链接到填充组合框的表,可能是“项类型”
    • 列表字段-要显示的“项目类型”字段的名称,可能是“名称”
    • key field(关键字段)-“item_types”(项目类型)字段的名称,该字段将插入到项目记录中,可能是“item_types”
    填充组合框的表格永远不会被编辑

    您可以在发布新的/编辑的“项目”记录之前验证这些值

    如果需要,我可以向您展示如何使用非数据感知组合框,但是使用数据感知版本更容易

    关于验证,我在编辑对话框中使用以下代码模板

    Function TEditQuestion.Execute (n: longint): boolean;
    var
     gen: longint;
    
    begin
     sdsEditQuestion.params[0].asinteger:= n;  // TSQLDataSet
     with qEditQuestion do                     // TClientDataSet
      begin
       open;
       if n = -1 then                          // new record
        begin
         caption:= 'New record';
         insert;
         fieldbyname ('alive').asinteger:= 1;
         // initialise necessary fields in the dataset
        end
       else caption:= 'Editing record ' + inttostr (n);
    
       edit;
       if showmodal = mrOK then
        begin
         // validation code comes here. Set 'result' to true if everything is ok
         if result then
          begin
           if n = -1 then
            begin
             with qGenID do
              begin
               open;
               gen:= fields[0].asinteger;    // get new value from generator
               close
              end;
    
             FieldByName ('id').asinteger:= gen;
            end;
           post;
           applyupdates (0)
          end
         else cancel  // showmodal = OK, result = false
       else           // showmodal cancelled
        begin
         cancel;
         result:= false
        end;
      end             // with qEditQuestion
     end;
    

    如果我理解正确,您希望使用DBLookupComboBox。必须为以下属性提供值

    • 数据源-链接到您正在编辑的表,可能是“项”
    • datafield—您正在编辑的表中字段的名称,可能是“item\u type”
    • listsource-链接到填充组合框的表,可能是“项类型”
    • 列表字段-要显示的“项目类型”字段的名称,可能是“名称”
    • key field(关键字段)-“item_types”(项目类型)字段的名称,该字段将插入到项目记录中,可能是“item_types”
    填充组合框的表格永远不会被编辑

    您可以在发布新的/编辑的“项目”记录之前验证这些值

    如果需要,我可以向您展示如何使用非数据感知组合框,但是使用数据感知版本更容易

    关于验证,我在编辑对话框中使用以下代码模板

    Function TEditQuestion.Execute (n: longint): boolean;
    var
     gen: longint;
    
    begin
     sdsEditQuestion.params[0].asinteger:= n;  // TSQLDataSet
     with qEditQuestion do                     // TClientDataSet
      begin
       open;
       if n = -1 then                          // new record
        begin
         caption:= 'New record';
         insert;
         fieldbyname ('alive').asinteger:= 1;
         // initialise necessary fields in the dataset
        end
       else caption:= 'Editing record ' + inttostr (n);
    
       edit;
       if showmodal = mrOK then
        begin
         // validation code comes here. Set 'result' to true if everything is ok
         if result then
          begin
           if n = -1 then
            begin
             with qGenID do
              begin
               open;
               gen:= fields[0].asinteger;    // get new value from generator
               close
              end;
    
             FieldByName ('id').asinteger:= gen;
            end;
           post;
           applyupdates (0)
          end
         else cancel  // showmodal = OK, result = false
       else           // showmodal cancelled
        begin
         cancel;
         result:= false
        end;
      end             // with qEditQuestion
     end;
    


    您可以将OnValidate-Event添加到
    项中。fk\u项类型
    字段claasic组合框可以填充项。AddObject(DisplayText,TObject(ID))。。。但是,您也可以使用TDBlookupComboBox而不分配数据源和数据字段,并使用属性KeyValue手动分配给item.fk_item_type。@bummi我看不到哪里可以“将事件添加到我的字段”。你是说数据库触发器吗?我在DBLookupComboBox的事件列表中没有看到名为“OnValidate”的事件。@bummi我不知道Items.AddObject,听起来很有趣。我已经尝试过不分配数据源/数据字段,但是编辑字段中没有显示任何内容(仅在下拉列表中)。让我们为
    项添加OnValidate-Event。fk_item_type
    字段claasic组合框可以填充项。AddObject(DisplayText,TObject(ID))。。。但是,您也可以使用TDBlookupComboBox而不分配数据源和数据字段,并使用属性KeyValue手动分配给item.fk_item_type。@bummi我看不到哪里可以“将事件添加到我的字段”。你是说数据库触发器吗?我在DBLookupComboBox的事件列表中没有看到名为“OnValidate”的事件。@bummi我不知道Items.AddObject,听起来很有趣。我已经尝试过不分配DataSource/DataField,但是在编辑字段中没有显示任何内容(仅在下拉列表中)。让我们看看,我并不固定使用DBLookupComboBox,只要是最容易完成任务的。你是说当用户做出选择时,数据源表不会被更改吗?@Zalumon:只有在你发布更改后,表才会被更改。通常,在用户按下“编辑”对话框上的“确定”按钮后会发生这种情况。您可以在发布数据之前验证OKBtnClick事件中的数据。我将在我的答案中添加一些代码,使其更清晰。啊,太好了,这可能解决了我的“问题”。不需要代码,这正是我想做的。@Zalumon:如果我的答案解决了你的问题,你能把它标记为选中的答案吗?当然,我花了整整一天的时间才真正测试了这个问题。我不固定使用DBLookupComboBox,只要最容易完成我的任务就行。你是说当用户做出选择时,数据源表不会被更改吗?@Zalumon:只有在你发布更改后,表才会被更改。通常,在用户按下“编辑”对话框上的“确定”按钮后会发生这种情况。您可以在发布数据之前验证OKBtnClick事件中的数据。我会在我的答案中添加一些代码,让它更清楚。啊,那个