快速实现主从表编辑,实现多个不定长从表

本文介绍了如何根据电子表格创建数据库表,配置订单-订单明细和订单-客户的一对一和一对多主从关系。通过关联设计设置主键和外键,然后测试运行结果,最后展示了一段代码来在面板中绘制字段列表面板。
摘要由CSDN通过智能技术生成

目录

1 前言

2 不定长表、定长表的定义

3 根据已有的电子表格制作数据库表并导入数据

3.1 订单

3.2 订单明细

3.3 客户

4 配置主从关联关系

5 继续增加一个主从关联关系 

 6 测试一下运行结果

 7 一段代码用于实现在panel中画出字段列表面板


1 前言

实际工作中,经常遇到一对多的主从表编辑需求,例如,主表是订单列表,从表是每个订单包含的一个或多个产品信息。

这里尝试实现以下主从表编辑:

订单——订单明细,一对多

订单——客户,一对一

2 不定长表、定长表的定义

  •  不定长表是指,与主表某条记录对应的从表记录数量不定,例如一个订单中,可能包含1种产品,也可能包含多种产品。
  •  定长表与不定长表相反。例如,某个班级的学生明细为主表,对应的从表是每个学生的学科分数情况,每个学生对应的行数是固定的。

定长表与不定长表,需要不一样的处理。

3 根据已有的电子表格制作数据库表并导入数据

 与上一篇操作相同,制作3个表:

3.1 订单

 

3.2 订单明细

 

3.3 客户

 

4 配置主从关联关系

工具——关联设计

注意是主表的订单ID字段与从表的订单ID进行关联,拖放的时候一定不要搞错了。

 这样就完成了一个主从关系的配置。完成后,在编辑列表中自动显示出来。

双击可看到效果。

5 继续增加一个主从关联关系 

订单表的客户ID字段与客户表的客户ID字段进行关联,完成后在主界面左上角编辑列表中自动显示出名称。

 6 测试一下运行结果

由于两个主从关系指向同一个主表,所以在从表界面中,显示2个主从关系选项卡,可以切换使用。

 7 一段代码用于实现在panel中画出字段列表面板

本来想实现可以自由拖动面板位置、拖放后在2个字段之间连线、保存面板状态等功能,太费时间,以后再说。这里仅仅实现最基本功能。

// 根据表名称画字段列表面板
procedure TFormLinks.drawTbl(parName, tblOrViewName, table_or_view: string; bCreateOrDestroy: boolean);
var
  //iLinks: integer;
  APanel: TPanel;
  ACheckListBoxFldCn: TCheckListBox;
  AListBoxTblEn, AListBoxFldEn: TListBox;
  ALabel: TLabel;
  //sql, sLeftPanelTop, sLeftPanelLeft, sRightPanelTop, sRightPanelLeft, linkNameTmp, srcTblTmp, dstTblTmp,
    tblNameCn,
    sFldCn, sFldEn: string;
begin

  // 创建 table 面板
  if bCreateOrDestroy = true then
  begin
    tblNameCn := clbTablesCnTobeChked.Items[clbTablesCnTobeChked.ItemIndex];
    memo1.append('tblNameCn: ' + tblNameCn);


    APanel := TPanel.Create(self);
    APanel.Name := 'panel_' + tblOrViewName;
    APanel.Parent := PanelMain;
    APanel.Caption := '';
    APanel.Hint := '';

    if ifMouseClick = True then // 如果鼠标单击表名生成的panel
    begin

      if (panel_left + checkedTableCnt * 200) < PanelMain.Width then
        APanel.Left := panel_left + checkedTableCnt * 300
      else
        APanel.Left := PanelMain.Width - 200;

      //memo1.append('APanel.Left: ' + intToStr(APanel.Left));

      APanel.Top := panel_top; // + (checkedTableCnt mod 2) * 100;
      //memo1.append('APanel.Top: ' + intToStr(APanel.Top));
    end
    else  // 如果不是鼠标点击表名生成的,则从数据库中读取位置信息
    begin

    end;

    APanel.Height := 300; //ZROQuery.RecordCount * 20 + 30;
    APanel.Width := 180;


    // 中文字段名列表
    if Assigned(FindComponent('clb_' + tblOrViewName)) then
      FindComponent('clb_' + tblOrViewName).Destroy;

    ACheckListBoxFldCn := TCheckListBox.Create(self);
    ACheckListBoxFldCn.Name := 'clb_' + tblOrViewName;
    ACheckListBoxFldCn.Parent := TPanel(FindComponent('panel_' + tblOrViewName));
    ACheckListBoxFldCn.Height := 300; //ZROQuery.RecordCount * 20;
    ACheckListBoxFldCn.Align := alClient;
    //ACheckListBoxFldCn.Left:=0;
    //ACheckListBoxFldCn.Top:=40;

    ACheckListBoxFldCn.DragMode := dmAutomatic;

     赋予创建的 CheckListBox 自定义函数
    ACheckListBoxFldCn.OnClick := @ACheckListBoxClick;
     自定义 复选列表 复选事件
    //ACheckListBoxFldCn.OnClickCheck := ACheckListBoxClickCheck;

    ACheckListBoxFldCn.OnDragOver := @ACheckListBoxDragOver;
    ACheckListBoxFldCn.OnDragDrop := @ACheckListBoxDragDrop;

    // 创建 listbox 用于记录原始英文表名(用于记录原始表名称)
    if Assigned(FindComponent('lbt_' + tblOrViewName)) then
      FindComponent('lbt_' + tblOrViewName).Destroy;

    AListBoxTblEn := TListBox.Create(self);
    AListBoxTblEn.Name := 'lbt_' + tblOrViewName;
    AListBoxTblEn.Parent := TPanel(FindComponent('panel_' + tblOrViewName));
    AListBoxTblEn.Height := 300; //ZROQuery.RecordCount * 10;
    AListBoxTblEn.Width := 100;
    AListBoxTblEn.Left := 60;
    AListBoxTblEn.Top := 40;
    AListBoxTblEn.Visible := false;

    //memo1.Append('创建了:' + 'lbt_' + tblOrViewName);

    // 创建 listbox 用于记录英文字段名(处理视图时用于查找英文字段)
    if Assigned(FindComponent('lb_' + tblOrViewName)) then
      FindComponent('lb_' + tblOrViewName).Destroy;

    AListBoxFldEn := TListBox.Create(self);
    AListBoxFldEn.Name := 'lb_' + tblOrViewName;
    AListBoxFldEn.Parent := TPanel(FindComponent('panel_' + tblOrViewName));
    AListBoxFldEn.Height := 300; // ZROQuery.RecordCount * 10;
    AListBoxFldEn.Width := 100;
    AListBoxFldEn.Left := 90;
    AListBoxFldEn.Top := 120;
    AListBoxFldEn.Visible := false;


    ALabel := TLabel.Create(self);
    ALabel.Name := 'lbl_' + tblOrViewName;
    ALabel.Caption := tblNameCn;
    ALabel.Parent := TPanel(FindComponent('panel_' + tblOrViewName));
    ALabel.Align:= alTop;
    //ALabel.Top := 0; //ACheckListBoxFldCn.Top - 17;
    //ALabel.Left := 0; //ACheckListBoxFldCn.Left + 5;
    ALabel.BorderSpacing.Left := 5;
    ALabel.BorderSpacing.Bottom := 5;
    //ALabel.Color := $7FFF0000;

    ACheckListBoxFldCn.Clear;
    //AListBoxTblEn.Clear;
    AListBoxFldEn.Clear;

    Form_main.queryFields.disablecontrols;
    //ACheckListBoxEn.Clear;
    Form_main.queryFields.First;
    while not Form_main.queryFields.EOF do
    begin

      if Form_main.queryFields.FieldByName('TABLE_NAME_EN').AsString = tblOrViewName then
      begin
        sFldCn := Form_main.queryFields.FieldByName('FIELD_NAME_CN').AsString;
        sFldEn := Form_main.queryFields.FieldByName('FIELD_NAME_EN').AsString;

        ACheckListBoxFldCn.Items.Add(sFldCn);

        AListBoxTblEn.items.Add(tblOrViewName);
        AListBoxFldEn.Items.Add(sFldEn);
      end;


      Form_main.queryFields.Next;
    end;

    checkedTableCnt := checkedTableCnt + 1;
  end;
  Form_main.queryFields.EnableControls;



end;  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值