unit CreateTemplateU; (* WorldVistA Configuration Utility (c) 8/2008 Kevin Toppenberg Programmed by Kevin Toppenberg, Eddie Hagood Family Physicians of Greeneville, PC 1410 Tusculum Blvd, Suite 2600 Greeneville, TN 37745 kdtop@yahoo.com This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *) interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, Grids, ExtCtrls; type TCreateTemplateForm = class(TForm) BottomPanel: TPanel; TopPanel: TPanel; TemplateGrid: TStringGrid; btnCancel: TBitBtn; btnSave: TBitBtn; Label1: TLabel; btnOpen: TBitBtn; btnAddField: TBitBtn; cboAddField: TComboBox; cboRemoveField: TComboBox; btnDelField: TBitBtn; btnDone: TBitBtn; SaveDialog: TSaveDialog; OpenDialog: TOpenDialog; btnClear: TBitBtn; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure btnAddFieldClick(Sender: TObject); procedure btnDelFieldClick(Sender: TObject); procedure btnSaveClick(Sender: TObject); procedure btnOpenClick(Sender: TObject); procedure btnClearClick(Sender: TObject); procedure btnDoneClick(Sender: TObject); private { Private declarations } BlankList : TStringList; RequiredList, FieldsList : TStringList; FFileNum : String; FModified : boolean; procedure LoadGrid(ReqList,FieldsList : TStringList); procedure PrepLists(BlankList,ReqList,FieldsList : TStringList); procedure LoadCombos(FieldsList : TStringList); procedure AddRow(oneEntry : string; Fixed : boolean); function MakeOneEntry(fldName,fldNum : string) : string; procedure LoadTemplate(fileName : string); procedure ClearGrid; procedure ClearComboBoxes; procedure MoveAddListToDelList(oneEntry : string); function DoSaveClick : TModalResult; public { Public declarations } procedure PrepForm (FileNum : String); procedure GetNumName(oneEntry : string; var fldName,fldNum : string); end; var CreateTemplateForm: TCreateTemplateForm; implementation {$R *.dfm} uses SubFilesU, ORNet, ORFn, MainU, StrUtils; procedure TCreateTemplateForm.PrepForm (FileNum : String); begin FFileNum := FileNum; ClearComboBoxes; PrepLists(BlankList,RequiredList,FieldsList); LoadGrid(RequiredList,FieldsList); LoadCombos(FieldsList); FModified := false; end; procedure TCreateTemplateForm.ClearComboBoxes; begin; cboAddField.Items.Clear; cboAddField.Text := ''; cboRemoveField.Items.Clear; cboRemoveField.Text := ''; end; procedure TCreateTemplateForm.PrepLists(BlankList,ReqList,FieldsList : TStringList); var i,j : integer; oneEntry : string; fldName,fldNum,fldCodes : string; tempS : string; reqField : boolean; begin if BlankList.Count=0 then begin MainForm.GetBlankFileInfo(FFileNum, BlankList); //returns: FileNum^^FieldNum^^FieldName^More DDInfo end; ReqList.Clear; FieldsList.Clear; //---- note: for now I am going to hard code the required fields in. ------ ReqList.Add('.01^'); //NAME ReqList.Add('.02^'); //SEX ReqList.Add('.03^'); //DOB ReqList.Add('.09^'); //SSN ReqList.Add('0^'); //A 'pseudoField', for use with Health Record number ReqList.Add('.301^^NO'); //SERVICE CONNECTED? default should be NO ReqList.Add('391^^NON-VETERAN (OTHER)'); //TYPE default should be NON-VETERAN (OTHER) ReqList.Add('994^^NO'); //MULTIPLE BIRTH INDICATOR default should be NO ReqList.Add('1901^^NO'); //VETERAN (Y/N)? default should be NO for i:= 0 to BlankList.Count-1 do begin oneEntry := BlankList.Strings[i]; if oneEntry = '1^Success' then begin //substitute status line with pseudoField, HRN oneEntry:='^^0^^Health Record Number (HRN)^F' end; fldName := piece(oneEntry,'^',5); fldNum := piece(oneEntry,'^',3); fldCodes := piece(oneEntry,'^',6); reqField := false; for j := 0 to ReqList.Count-1 do begin if Pos(fldNum+'^',ReqList.Strings[j])=1 then begin tempS := ReqList.Strings[j]; SetPiece(tempS,'^',2,fldName); ReqList.Strings[j] := tempS; reqField := true; break; end; end; if reqField then continue; if Pos('C',fldCodes)>0 then continue; //computed if Pos('P',fldCodes)>0 then continue; //pointer to file if MainForm.IsSubFile(fldCodes,tempS) then continue; //no subfiles (including WP fields) if Pos('I',fldCodes)>0 then continue; //marked uneditable. FieldsList.Add(fldNum+'^'+fldName); end; end; procedure TCreateTemplateForm.LoadGrid(ReqList,FieldsList : TStringList); var i : integer; oneEntry : string; begin ClearGrid; for i := 0 to ReqList.Count-1 do begin oneEntry := ReqList.Strings[i]; AddRow(oneEntry,true); end; end; procedure TCreateTemplateForm.ClearGrid; begin TemplateGrid.FixedCols := 0; TemplateGrid.FixedRows := 1; TemplateGrid.RowCount := 2; TemplateGrid.Cells[0,0] := 'NAME:'; TemplateGrid.Cells[1,0] := 'NUMBER:'; TemplateGrid.Cells[2,0] := 'DEFAULT:'; TemplateGrid.Cells[0,1] := ''; TemplateGrid.Cells[1,1] := ''; TemplateGrid.Cells[2,1] := ''; TemplateGrid.ColWidths[0] := 300; TemplateGrid.ColWidths[1] := 100; TemplateGrid.ColWidths[0] := 300; // TemplateGrid end; procedure TCreateTemplateForm.AddRow(oneEntry : string; Fixed : boolean); //oneEntry format: fldNum^fldName //optional format: fldNum^fldName^DefaultValue var i,j : integer; fldName,fldNum : string; defaultValue : string; begin GetNumName(oneEntry,fldName,fldNum); defaultValue := piece(oneEntry,'^',3); //Add : ensure row doesn't already exist; for j := 0 to TemplateGrid.RowCount-1 do begin if TemplateGrid.Cells[1,j] = fldNum then exit; end; i := TemplateGrid.RowCount-1; if TemplateGrid.Cells[0,i] <> '' then begin TemplateGrid.RowCount := TemplateGrid.RowCount + 1; end; i := TemplateGrid.RowCount-1; TemplateGrid.Cells[0,i] := fldName; TemplateGrid.Cells[1,i] := fldNum; TemplateGrid.Cells[2,i] := defaultValue; end; procedure TCreateTemplateForm.LoadCombos(FieldsList : TStringList); var i : integer; oneEntry : string; fldName,fldNum : string; begin cboAddField.Items.clear; for i := 0 to FieldsList.Count-1 do begin oneEntry := FieldsList.Strings[i]; GetNumName(oneEntry,fldName,fldNum); cboAddField.Items.Add(MakeOneEntry(fldName,fldNum)); end; cboAddField.ItemIndex := 0; end; procedure TCreateTemplateForm.FormCreate(Sender: TObject); begin BlankList := TStringList.create; RequiredList := TStringList.create; FieldsList := TStringList.create; ClearGrid; end; procedure TCreateTemplateForm.FormDestroy(Sender: TObject); begin BlankList.Free; RequiredList.Free; FieldsList.Free; end; procedure TCreateTemplateForm.btnAddFieldClick(Sender: TObject); var i : integer; oneEntry,tempEntry : string; fldName,fldNum : string; exists: boolean; begin FModified := true; oneEntry := cboAddField.Text; if oneEntry = '' then exit; GetNumName(oneEntry,fldName,fldNum); if (fldNum = '') or (fldName = '') then exit; tempEntry := fldNum + '^' + fldName; //Add : ensure row doesn't already exist; exists := false; for i := 0 to TemplateGrid.RowCount-1 do begin if TemplateGrid.Cells[1,i] = fldNum then begin exists := true; break; end; end; if not exists then begin AddRow(tempEntry,false); MoveAddListToDelList(tempEntry); end; end; procedure TCreateTemplateForm.MoveAddListToDelList(oneEntry : string); //Move entry from Add list to delete list. var i : integer; fldName,fldNum : string; tempEntry : string; begin GetNumName(oneEntry,fldName,fldNum); tempEntry := MakeOneEntry(fldName,fldNum); i := cboAddField.Items.IndexOf(tempEntry); if i > -1 then cboAddField.Items.Delete(i); if i < cboAddField.Items.Count then cboAddField.ItemIndex := i else cboAddField.ItemIndex := cboAddField.Items.Count-1; //if cboAddField.Items.Count > 0 then cboAddField.ItemIndex := 0 else cboAddField.ItemIndex := -1; cboRemoveField.Items.Add(tempEntry); cboRemoveField.ItemIndex := cboRemoveField.Items.Count - 1; end; procedure TCreateTemplateForm.GetNumName(oneEntry : string; var fldName,fldNum : string); begin if Pos('^',oneEntry)>0 then begin fldNum := piece(oneEntry,'^',1); fldName := piece(oneEntry,'^',2); end else begin fldNum := piece(oneEntry,'{',2); fldNum := piece(fldNum,'}',1); fldName := piece(oneEntry,'{',1); fldName := Trim(fldName); end; end; function TCreateTemplateForm.MakeOneEntry(fldName,fldNum : string) : string; begin result := fldName+' {'+fldNum+'}'; end; procedure TCreateTemplateForm.btnDelFieldClick(Sender: TObject); var i : integer; oneEntry : string; fldName,fldNum : string; delRow : integer; begin oneEntry := cboRemoveField.Text; GetNumName(oneEntry,fldName,fldNum); if fldNum = '' then exit; delRow := -1; for i := 1 to TemplateGrid.RowCount-1 do begin if TemplateGrid.Cells[1,i] = fldNum then begin delRow := i; break; end; end; if delRow = -1 then exit; i := cboRemoveField.Items.IndexOf(oneEntry); if i > -1 then cboRemoveField.Items.Delete(i); cboRemoveField.ItemIndex := cboRemoveField.Items.Count - 1; cboAddField.Items.Insert(0,oneEntry); cboAddField.ItemIndex := 0; for i := delRow to TemplateGrid.RowCount-2 do begin TemplateGrid.Cells[0,i] := TemplateGrid.Cells[0,i+1]; TemplateGrid.Cells[1,i] := TemplateGrid.Cells[1,i+1]; end; TemplateGrid.RowCount := TemplateGrid.RowCount -1; end; procedure TCreateTemplateForm.btnSaveClick(Sender: TObject); begin DoSaveClick; MessageDlg('You have created an empty registration Template.'+#10+#13+ 'Now you should EDIT IT with your favorite spreadsheet '+#10+#13+ 'application (such as Microsoft Excel, or Open Office,) '+#10+#13+ 'filling it with patient demographic data.'+#10+#13+ #10+#13+ 'Hint #1: try just a few patients initially, to make sure'+#10+#13+ ' that all is working properly. Built in safeguards will'+#10+#13+ ' prevent duplicate registrations on subsequent runs.'+#10+#13+ #10+#13 {+ 'Hint #2: Open Office tends to format the field number (e.g. ".01")'+#10+#13+ ' as a decimal, and converts it to '0.01'. This will prevent'+#10+#13+ ' successful upload. In general field numbers do NOT have a "0"'+#10+#13+ ' before a decimal (".")' } ,mtInformation,[mbOK],0); end; function TCreateTemplateForm.DoSaveClick : TModalResult; var TemplateLines : TStringList; row : integer; Line1,Line2,SampleLine : string; begin Line1 := 'Field NAME:'; Line2 := 'Field NUMBER:'; SampleLine := 'Put a patient''s data on this row -->'; If SaveDialog.Execute then begin TemplateLines := TStringList.Create; for row := 1 to TemplateGrid.RowCount-2 do begin Line1 := Line1 + #9 + '"' + TemplateGrid.Cells[0,row] + '"'; Line2 := Line2 + #9 + '"<'+TemplateGrid.Cells[1,row]+'>"'; SampleLine := SampleLine + #9 + '"' + TemplateGrid.Cells[2,row] + '"'; end; TemplateLines.Add(Line1); TemplateLines.Add(Line2); TemplateLines.Add(SampleLine); TemplateLines.Add(SampleLine); TemplateLines.Add(SampleLine); TemplateLines.Add('etc... (As many rows as needed)'); TemplateLines.Add(' '); TemplateLines.Add('When done, save file and import with'); TemplateLines.Add(' the WorldVista Config Utility.'); TemplateLines.Add('Save in CSV format, using TAB as field'); TemplateLines.Add(' delimiter, and " as text delimiter.'); TemplateLines.SaveToFile(SaveDialog.FileName); TemplateLines.Free; Result := mrOK; FModified := false; end else begin Result := mrCancel; end; end; procedure TCreateTemplateForm.btnOpenClick(Sender: TObject); begin if OpenDialog.Execute then begin LoadTemplate(OpenDialog.FileName); end; end; procedure TCreateTemplateForm.LoadTemplate(fileName : string); var Lines: TStringList; Line1List,Line2List : TStringList; oneLine : string; i : integer; fldName,fldNum : string; oneEntry : string; begin Lines := TStringList.Create; Line1List := TStringList.Create; Line2List := TStringList.Create; Lines.LoadFromFile(fileName); if Lines.Count < 2 then begin MessageDlg('Template file has less than 2 lines.'+#10+#13+ 'Doesn''t appear to be valid template.', mtError,[mbOK],0); exit; end; ClearGrid; oneLine := Lines.Strings[0]; PiecesToList(oneLine, #9, Line1List); oneLine := Lines.Strings[1]; PiecesToList(oneLine, #9, Line2List); for i := 1 to Line1List.Count-1 do begin fldName := Line1List.Strings[i]; if i < Line2List.Count then begin fldNum := Line2List.Strings[i]; fldNum := AnsiReplaceStr(fldNum,'"<',''); fldNum := AnsiReplaceStr(fldNum,'>"',''); end else begin fldNum := '??'; end; oneEntry := fldNum+'^'+fldName; AddRow(oneEntry,false); MoveAddListToDelList(oneEntry); end; Lines.Free; Line1List.Free; Line2List.Free; end; procedure TCreateTemplateForm.btnClearClick(Sender: TObject); begin //add confirmation box. if MessageDlg('Erase All Current Fields?',mtConfirmation,mbOKCancel,0) = mrOK then begin PrepForm (FFileNum); end; end; procedure TCreateTemplateForm.btnDoneClick(Sender: TObject); var tempModal : TModalResult; begin if FModified then begin tempModal := MessageDlg('Save Template Before Leaving?',mtConfirmation,mbYesNoCancel,0); end else begin tempModal := mrNo; end; case tempModal of mrYes : begin tempModal := DoSaveClick; if tempModal = mrOK then ModalResult := mrOK; //if tempModal = mrCancel, then do nothing. end; mrNo : ModalResult := mrOK; mrCancel : // do nothing. end; {case} end; end.