unit BatchInsertBillsFrm; interface uses BillsCompileDm, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ZJGrid, sdIDTree, dxBar, sdGridDBA, ComCtrls; type TInsertType = (itChild, itNextSibling); TBatchInsertBillsForm = class(TForm) pnlButton: TPanel; btnOK: TButton; btnCancel: TButton; dxpmInsertBills: TdxBarPopupMenu; pnlAllGrid: TPanel; pnlPositon_Bills: TPanel; pnlPosition: TPanel; lblPostion: TLabel; zgPosition: TZJGrid; pnlPositionSpr: TPanel; pnlBills: TPanel; lblBills: TLabel; zgBills: TZJGrid; pnlBillsSpr: TPanel; pnlDealBills: TPanel; pnlOther: TPanel; leBeginCode: TLabeledEdit; leDrawingCode: TLabeledEdit; zgDealBills: TZJGrid; pnlDealBillsSpr: TPanel; lblDealBills: TLabel; lblHint: TLabel; sgdDealBills: TsdGridDBA; udBeginCode: TUpDown; procedure zgPositionCustomPaste(Sender: TObject; ABounds: TRect; ASourSheet: TZjSheet); procedure zgBillsCustomPaste(Sender: TObject; ABounds: TRect; ASourSheet: TZjSheet); procedure btnOKClick(Sender: TObject); procedure zgPositionMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure zgBillsCellTextChanged(Sender: TObject; Col, Row: Integer); procedure zgDealBillsMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure leBeginCodeKeyPress(Sender: TObject; var Key: Char); procedure zgPositionCellTextChanged(Sender: TObject; Col, Row: Integer); private FInsertType: TInsertType; FBillsCompileData: TBillsCompileData; FParentCode: string; procedure ResetPositionGridHead; procedure ResetBillsGridHead; procedure PasteData(AGrid: TZJGrid; ABounds: TRect; ASourSheet: TZjSheet); procedure SetRowAndColumnCount(AGrid: TZJGrid; ASourSheet: TZjSheet); procedure LoadParentCode; function ReplaceLastNum(const ACode: string; ARow: Integer): string; function GetXmjCode(ARow: Integer): string; procedure AddXmjNode(ARow, AParentID, ANextSiblingID: Integer); procedure AddBillsNode(AQtyRow, ARow: Integer; AParent: TsdIDTreeNode); procedure AddBillsNodes(AQtyRow: Integer; AParent: TsdIDTreeNode); procedure BatchAddBillsNodes(AParentID, ANextSiblingID: Integer); public procedure Init(ABillsCompileData: TBillsCompileData; AInsertType: TInsertType); procedure Execute; end; procedure AddLeafBills(ABillsCompileData: TBillsCompileData; AInsertType: TInsertType); implementation uses sdDB, UtilMethods, ProjectData; {$R *.dfm} procedure AddLeafBills(ABillsCompileData: TBillsCompileData; AInsertType: TInsertType); var InsertBillsForm: TBatchInsertBillsForm; begin InsertBillsForm := TBatchInsertBillsForm.Create(nil); try InsertBillsForm.Init(ABillsCompileData, AInsertType); if InsertBillsForm.ShowModal = mrOK then InsertBillsForm.Execute; finally InsertBillsForm.Free; end; end; { TAddLeafBillsForm } procedure TBatchInsertBillsForm.AddXmjNode(ARow, AParentID, ANextSiblingID: Integer); var stnNode: TsdIDTreeNode; begin if zgPosition.Cells[1, ARow].Text = '' then Exit; stnNode := FBillsCompileData.BillsCompileTree.Add(AParentID, ANextSiblingID); with stnNode.Rec do begin ValueByName('Code').AsString := GetXmjCode(ARow);{ReplaceLastNum(leBeginCode.Text, ARow);} ValueByName('Name').AsString := zgPosition.Cells[1, ARow].Text; ValueByName('DrawingCode').AsString := leDrawingCode.Text; end; AddBillsNodes(ARow, stnNode); end; procedure TBatchInsertBillsForm.BatchAddBillsNodes(AParentID, ANextSiblingID: Integer); var iRow: Integer; begin for iRow := 1 to zgPosition.RowCount - 1 do AddXmjNode(iRow, AParentID, ANextSiblingID); end; procedure TBatchInsertBillsForm.Execute; begin with FBillsCompileData.BillsCompileTree do begin if FInsertType = itChild then begin if not Assigned(Selected) then Exit; BatchAddBillsNodes(Selected.ID, -1); FBillsCompileData.Calculate(Selected.ID); end else if FInsertType = itNextSibling then begin if not Assigned(Selected.Parent) then Exit; BatchAddBillsNodes(Selected.ParentID, Selected.NextSiblingID); FBillsCompileData.Calculate(Selected.ParentID); end; end; end; procedure TBatchInsertBillsForm.Init(ABillsCompileData: TBillsCompileData; AInsertType: TInsertType); begin FBillsCompileData := ABillsCompileData; sgdDealBills.DataView := TProjectData(ABillsCompileData.ProjectData).DealBillsData.sdvDealBills; FInsertType := AInsertType; if FInsertType = itChild then Caption := '批量插入子项' else if FInsertType = itNextSibling then Caption := '批量插入后项'; ResetPositionGridHead; ResetBillsGridHead; LoadParentCode; end; procedure TBatchInsertBillsForm.PasteData(AGrid: TZJGrid; ABounds: TRect; ASourSheet: TZjSheet); var iCol, iRow: Integer; begin for iRow := 0 to ASourSheet.RowCount - 1 do for iCol := 0 to ASourSheet.ColCount - 1 do begin with AGrid.Cells[iCol + ABounds.Left , iRow + ABounds.Top] do if CanEdit then Text := ASourSheet.Values[iCol, iRow]; end; end; function TBatchInsertBillsForm.ReplaceLastNum(const ACode: string; ARow: Integer): string; var sgs: TStringList; begin sgs := TStringList.Create; try sgs.Delimiter := '-'; sgs.DelimitedText := ACode; sgs[sgs.Count - 1] := IntToStr(StrToInt(sgs[sgs.Count - 1]) + ARow - 1); Result := sgs.DelimitedText; finally sgs.Free; end; end; procedure TBatchInsertBillsForm.ResetPositionGridHead; var iCol: Integer; begin zgPosition.Cells[1, 0].Text := '部位'; zgPosition.ColWidths[1] := 120; for iCol := 2 to zgPosition.ColCount - 1 do begin zgPosition.Cells[iCol, 0].Text := '清单' + IntToStr(iCol - 1); zgPosition.ColWidths[iCol] := 50; end; end; procedure TBatchInsertBillsForm.SetRowAndColumnCount(AGrid: TZJGrid; ASourSheet: TZjSheet); begin if AGrid.ColCount < ASourSheet.ColCount + AGrid.CurCol then AGrid.ColCount := ASourSheet.ColCount + AGrid.CurCol; if AGrid.RowCount < ASourSheet.RowCount + AGrid.CurRow + 1 then AGrid.RowCount := ASourSheet.RowCount + AGrid.CurRow + 1; end; procedure TBatchInsertBillsForm.zgPositionCustomPaste(Sender: TObject; ABounds: TRect; ASourSheet: TZjSheet); begin SetRowAndColumnCount(TZJGrid(Sender), ASourSheet); ResetPositionGridHead; PasteData(TZJGrid(Sender), ABounds, ASourSheet); zgBills.RowCount := zgPosition.ColCount - 1; ResetBillsGridHead; end; procedure TBatchInsertBillsForm.zgBillsCustomPaste(Sender: TObject; ABounds: TRect; ASourSheet: TZjSheet); begin SetRowAndColumnCount(TZJGrid(Sender), ASourSheet); PasteData(TZJGrid(Sender), ABounds, ASourSheet); end; procedure TBatchInsertBillsForm.AddBillsNodes(AQtyRow: Integer; AParent: TsdIDTreeNode); var iRow: Integer; begin for iRow := 1 to zgBills.RowCount - 1 do AddBillsNode(AQtyRow, iRow, AParent); end; procedure TBatchInsertBillsForm.AddBillsNode(AQtyRow, ARow: Integer; AParent: TsdIDTreeNode); var stnNode: TsdIDTreeNode; fQuantity: Double; begin if (zgBills.Cells[1, ARow].Text = '') or (zgPosition.Cells[ARow + 1, AQtyRow].Text = '') or not TryStrToFloat(zgPosition.Cells[ARow + 1, AQtyRow].Text, fQuantity) then Exit; stnNode := FBillsCompileData.BillsCompileTree.Add(AParent.ID, -1); with stnNode.Rec do begin ValueByName('B_Code').AsString := zgBills.Cells[1, ARow].Text; ValueByName('Name').AsString := zgBills.Cells[2, ARow].Text; ValueByName('Units').AsString := zgBills.Cells[3, ARow].Text; ValueByName('Price').AsFloat := StrToFloatDef(zgBills.Cells[4, ARow].Text, 0); ValueByName('OrgQuantity').AsFloat := StrToFloatDef(zgPosition.Cells[ARow + 1, AQtyRow].Text, 0); end; end; procedure TBatchInsertBillsForm.ResetBillsGridHead; var iRow: Integer; begin zgBills.Cells[1, 0].Text := '编号'; zgBills.ColWidths[1] := 80; zgBills.Cells[2, 0].Text := '名称'; zgBills.ColWidths[2] := 120; zgBills.Cells[3, 0].Text := '单位'; zgBills.ColWidths[3] := 60; zgBills.Cells[4, 0].Text := '单价'; zgBills.ColWidths[4] := 60; for iRow := 1 to zgBills.RowCount - 1 do zgBills.Cells[0, iRow].Text := '清单' + IntToStr(iRow); end; procedure TBatchInsertBillsForm.btnOKClick(Sender: TObject); function CheckGridHasData(AGrid: TZJGrid): Boolean; var iRow: Integer; begin Result := False; for iRow := 1 to AGrid.RowCount - 1 do if AGrid.Cells[1, iRow].Text <> '' then begin Result := True; Break; end; end; function CheckBeginCodeAvailable(const ACode: string): Boolean; var sgsCode: TStrings; iCode: Integer; begin sgsCode := TStringList.Create; try sgsCode.Delimiter := '-'; sgsCode.DelimitedText := ACode; Result := TryStrToInt(sgsCode[sgsCode.Count - 1], iCode); finally sgsCode.Free; end; end; begin if not CheckGridHasData(zgPosition) then ErrorMessage('请输入部位数量复核数据!') else if not CheckGridHasData(zgBills) then ErrorMessage('请输入清单编号等数据!') else if leBeginCode.Text = '' then ErrorMessage('请输入起始编号!') else if not CheckBeginCodeAvailable(leBeginCode.Text) then ErrorMessage('请输入规范的起始部位编号,如1或1-1等。') else ModalResult := mrOK; end; procedure TBatchInsertBillsForm.zgPositionMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Button = mbRight then dxpmInsertBills.PopupFromCursorPos; end; procedure TBatchInsertBillsForm.zgBillsCellTextChanged(Sender: TObject; Col, Row: Integer); var sB_Code: string; Rec: TsdDataRecord; begin if (Col = 1) and (Row > 0) then begin zgBills.Cells[Col, Row].Align := gaCenterLeft; sB_Code := zgBills.Cells[Col, Row].Text; if sB_Code = '' then Exit; with FBillsCompileData.BillsData do Rec := sddBills.Locate('B_Code', sB_Code); if Assigned(Rec) then begin zgBills.Cells[2, Row].Text := Rec.ValueByName('Name').AsString; zgBills.Cells[2, Row].Align := gaCenterLeft; zgBills.Cells[3, Row].Text := Rec.ValueByName('Units').AsString; zgBills.Cells[3, Row].Align := gaCenterLeft; zgBills.Cells[3, Row].Font.Name := 'smartSimSun'; zgBills.Cells[4, Row].Text := Rec.ValueByName('Price').AsString; zgBills.Cells[4, Row].Align := gaCenterRight; end; end else if (Col = 4) and (Row > 0) then begin zgBills.Cells[Col, Row].Value := PriceRoundTo( StrToFloatDef(zgBills.Cells[Col, Row].Text, 0)); zgBills.Cells[Col, Row].Align := gaCenterRight; end; end; procedure TBatchInsertBillsForm.zgDealBillsMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var i: Integer; begin if (Button = mbLeft) and (ssDouble in Shift) then for i := 1 to 4 do zgBills.Cells[i, zgBills.CurRow].Text := zgDealBills.Cells[i, zgDealBills.CurRow].Text; end; procedure TBatchInsertBillsForm.LoadParentCode; var Parent: TsdIDTreeNode; begin if FInsertType = itChild then Parent := FBillsCompileData.BillsCompileTree.Selected else if FInsertType = itNextSibling then Parent := FBillsCompileData.BillsCompileTree.Selected.Parent; FParentCode := Parent.Rec.ValueByName('Code').AsString; end; function TBatchInsertBillsForm.GetXmjCode(ARow: Integer): string; var iBeginCode: Integer; begin iBeginCode := StrToIntDef(leBeginCode.Text, 1); Result := Format('%s-%d', [FParentCode, iBeginCode + ARow - 1]); end; procedure TBatchInsertBillsForm.leBeginCodeKeyPress(Sender: TObject; var Key: Char); begin ValidInteger(Key); end; procedure TBatchInsertBillsForm.zgPositionCellTextChanged(Sender: TObject; Col, Row: Integer); begin if (Col > 1) and (Row > 0) then begin zgPosition.Cells[Col, Row].Value := QuantityRoundTo( StrToFloatDef(zgPosition.Cells[Col, Row].Text, 0)); zgPosition.Cells[Col, Row].Align := gaCenterRight; end; end; end.