С наступающими!
Сделал одну форму для добавления/редактирования записей через глобальную переменную и if else. Не знаю правильно ли, но пока работает.

Добрый день.
Поделитесь опытом (примером кода), если это не коммерческая тайна.
Как у Вас организовано, что кнопке можно назначить разные действия из списка (новая запись, показать запись, сохранить запись..), и что форма имеет отдельные действия (Start, NewRecord, ShowRecord...)?
В своём собственном проекте на Delphi XE3 для каждого действия приходится создавать отдельную форму.
А у Вас удобно тем, что для добавления и редактирования записи можно использовать одну форму.
Спасибо.

Спасибо. Работает.

Добрый вечер.
Столкнулся с проблемой регистронезависимого поиска по базе SQLite3.
Запрос вида: SELECT * FROM vymoghy WHERE borzhnyk LIKE "%'+Edit1.Text+'%" по тексту "ася" находит: "Вася", "Мася", но не "Ася".
Уже пробовал разные компоненты для подключения к БД, upper+AnsiUpperCase, lower+AnsiLowerCase, collate.

Спасибо.
Ещё вопрос.
У SQLite есть параметр "busytimeout=<milliseconds>".
А как его использовать?

Здравствуйте.
Сменил компоненты подключения к базе на ZeosDBO, - вроде работает. Но уже другая проблема.
Форма добавления новой записи у меня вызывается как модальная форма

procedure TForm1.Button1Click(Sender: TObject);
begin
   Form2.ShowModal;
end;

Код формы:

unit Unit2;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, sqldb, sqlite3conn, FileUtil, ZVDateTimePicker,
  DBZVDateTimePicker, curredit, dbdateedit, RTTICtrls, u_framework_components,
  u_extformatedits, U_ExtNumEdits, u_extsearchedit, U_ExtDBNavigator,
  JLabeledCurrencyEdit, JLabeledFloatEdit, JLabeledIntegerEdit, JDBLabeledEdit,
  jdblabeledintegeredit, ZDataset, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Spin, EditBtn, DbCtrls;

type

  { TForm2 }

  TForm2 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Edit5: TEdit;
    Edit6: TEdit;
    Edit7: TEdit;
    GroupBox1: TGroupBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Memo1: TMemo;
    ZQuery2: TZQuery;
    ZVDateTimePicker1: TZVDateTimePicker;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Edit3KeyPress(Sender: TObject; var Key: char);
    procedure Edit4KeyPress(Sender: TObject; var Key: char);
    procedure Edit6KeyPress(Sender: TObject; var Key: char);
    procedure Edit7KeyPress(Sender: TObject; var Key: char);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormShow(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.lfm}

uses Unit1;

{ TForm2 }

procedure TForm2.Button1Click(Sender: TObject);
   var
   last_record_count: integer;
   record_count: string;
begin
   ZQuery2.Close;
   ZQuery2.SQL.Clear;
   ZQuery2.SQL.Text:= 'SELECT MAX(record_count) FROM vymoghy';
   ZQuery2.Open;

   last_record_count := ZQuery2.Fields[0].AsInteger;
   if last_record_count <> 0 then record_count := IntToStr(last_record_count+1) else record_count := IntToStr(1);

   If Form1.ZConnection1.Connected then
   begin
   ZQuery2.Close;
   ZQuery2.SQL.Clear;
   ZQuery2.SQL.Add(Format('insert into vymoghy (record_count, data_vymoghy, borzhnyk, kod_borzhnyka, bank_borzhnyka, mfo_banku, rakhunok, suma, pryznachennja_platezhu) values ("%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s")',[record_count, FormatDateTime('YYYY-MM-DD 00:00:00.000', ZVDateTimePicker1.DateTime), Edit2.Text, Edit3.Text, Edit5.Text, Edit4.Text, Edit6.Text, StringReplace(Edit7.Text, ',', '.', [rfReplaceAll, rfIgnoreCase]), Memo1.Text]));
   ZQuery2.ExecSQL;
   end;

   Form2.Close;
end;

procedure TForm2.Button2Click(Sender: TObject);
begin
   Form2.Close;
end;

procedure TForm2.Edit3KeyPress(Sender: TObject; var Key: char);
begin
   case Key of
   '0'..'9': ;
   #8: ;  // the backspace key
   else Key:= #0;
   end;
end;

procedure TForm2.Edit4KeyPress(Sender: TObject; var Key: char);
begin
   case Key of
   '0'..'9': ;
   #8, #9: ;  // the backspace & tab key
   else Key:= #0;
   end;
end;

procedure TForm2.Edit6KeyPress(Sender: TObject; var Key: char);
begin
   case Key of
   '0'..'9': ;
   #8, #9: ;  // the backspace & tab key
   else Key:= #0;
   end;
end;

procedure TForm2.Edit7KeyPress(Sender: TObject; var Key: char);
begin
   case Key of
   '0'..'9': ;
   ',', #8, #9: ;  // the backspace & tab key
   else Key:= #0;
   end;
end;

procedure TForm2.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
   Form1.ZQuery1.Close;
   Form1.ZQuery1.SQL.Clear;
   Form1.ZQuery1.SQL.Text:='select * from vymoghy';
   Form1.ZQuery1.Open;
end;

procedure TForm2.FormShow(Sender: TObject);
   var
   last_record_count: integer;
   record_count: string;
begin
   ZVDateTimePicker1.DateTime:=now;
   ZQuery2.Close;
   ZQuery2.SQL.Clear;
   ZQuery2.SQL.Text:= 'SELECT MAX(record_count) FROM vymoghy';
   ZQuery2.Open;

   last_record_count := ZQuery2.Fields[0].AsInteger;
   if last_record_count <> 0 then record_count := IntToStr(last_record_count+1) else record_count := IntToStr(1);

   Edit1.text := record_count;
end;

{ TForm2 }

end.

После закрытия этой формы, данные компонентов (Edit, Memo,...) не очищаются. Когда снова открываешь форму, для добавления новой аписи, в компонентах сидят предыдущие значения.
До смены компонентов подключения такого не наблюдал.
Подскажите, куда копать.

Можно уточнить? А какая версия Delphi XE (7 или более ранняя?) и какой язык (Object Pascal или C++?)?
Извиняюсь за расспросы, но хочу для себя определиться с чего же лучше начать изучение.

А в какой среде Вы работаете,

Код сохранения записи написал так

procedure TForm2.Button1Click(Sender: TObject);
   var
   last_record_count: integer;
   record_count: string;
begin
   SQLQuery1.Close;
   SQLQuery1.SQL.Text:= 'SELECT MAX(record_count) FROM vymoghy';
   SQLQuery1.Open;

   last_record_count := SQLQuery1.Fields[0].AsInteger;
   if last_record_count <> 0 then record_count := IntToStr(last_record_count+1) else record_count := IntToStr(1);

   If Form1.SQLite3Connection1.Connected then
   begin
   SQLQuery1.Close;
   SQLQuery1.SQL.Clear;
   SQLQuery1.SQL.Add(Format('insert into vymoghy (record_count, data_vymoghy, borzhnyk, kod_borzhnyka, bank_borzhnyka, mfo_banku, rakhunok, suma, pryznachennja_platezhu) values ("%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s")',[record_count, FormatDateTime('YYYY-MM-DD 00:00:00.000', ZVDateTimePicker1.DateTime), Edit2.Text, Edit3.Text, Edit5.Text, Edit4.Text, Edit6.Text, Edit7.Text, Memo1.Text]));
   Form1.SQLTransaction1.Active := False;
   Form1.SQLTransaction1.Active := True;
   SQLQuery1.ExecSQL;
   Form1.SQLTransaction1.Commit;
   end;

   Form2.Close;
end;

и удалил Form1.SQLQuery1.Refresh; (обновление грида).
Но как теперь обновить грид?
Если добавить Form1.SQLQuery1.Refresh; в событие закрытия формы, то ругается на неактивный датасет, а если активировать Form1.SQLQuery1, то опять ругается на заблокированную базу.

Для подключения используются компоненты: SQLite3Connection1, SQLTransaction1, DataSource1, SQLQuery1 (для получения данных из БД), SQLQuery2 (для записи данных в БД).

Главная форма
Подключение к базе:

procedure TForm1.FormCreate(Sender: TObject);
begin
   sqlite3dyn.SQLiteDefaultLibrary := 'sqlite3.dll';
   SQLite3Connection1.DatabaseName := 'sqlite.db';
   SQLite3Connection1.Connected := True;
   SQLQuery1.Active := True;
end;

вычисляемое поле:

procedure TForm1.SQLQuery1CalcFields(DataSet: TDataSet);
begin
   SQLQuery1.FieldByName('zmist').AsString := ('Кошти боргу з ' + SQLQuery1.FieldByName('borzhnyk').AsString);
end;

кнопка поиска на главной форме:

procedure TForm1.Button5Click(Sender: TObject);
   var
   sqlwhere: string;
begin
   sqlwhere := '';
   if Edit1.Text <> '' then
   sqlwhere := Format('%s and %s', [sqlwhere, 'record_count = "'+Edit1.text+'"']);
   if ZVDateTimePicker1.Checked=True then
   sqlwhere := Format('%s and %s', [sqlwhere, 'strftime("%Y-%m-%d", data_vymoghy) >= "'+FormatDateTime('YYYY-MM-DD', ZVDateTimePicker1.DateTime)+'"']);
   if ZVDateTimePicker2.Checked=True then
   sqlwhere := Format('%s and %s', [sqlwhere, 'strftime("%Y-%m-%d", data_vymoghy) <= "'+FormatDateTime('YYYY-MM-DD', ZVDateTimePicker2.DateTime)+'"']);
   if Edit2.Text <> '' then
   sqlwhere := Format('%s and %s', [sqlwhere, 'borzhnyk LIKE "%'+Edit2.text+'%"']);
   if Edit3.Text <> '' then
   sqlwhere := Format('%s and %s', [sqlwhere, 'kod_borzhnyka = "'+Edit3.text+'"']);

   delete(sqlwhere,2,3);

   if sqlwhere='' then
   begin
   SQLQuery1.Active:=False;
   SQLQuery1.SQL.Text:= 'select * from vymoghy';
   SQLQuery1.Active:=True;
   end else
   begin
   SQLQuery1.Active:=False;
   SQLQuery1.SQL.Text:= 'select * from vymoghy where' + sqlwhere;
   SQLQuery1.Active:=True;
   end;
end;

Форма добавления новой записи
Запись нового значения счётчика в текстовое поле

procedure TForm2.FormShow(Sender: TObject);
   var
   last_record_count: integer;
   record_count: string;
begin
   SQLQuery1.Active:=False;
   SQLQuery1.SQL.Text:= 'SELECT MAX(record_count) FROM vymoghy';
   SQLQuery1.Open;
   Form1.SQLTransaction1.CommitRetaining;
   SQLQuery1.Active:=True;

   last_record_count := SQLQuery1.Fields[0].AsInteger;
   if last_record_count <> 0 then record_count := IntToStr(last_record_count+1) else record_count := IntToStr(1);

   Edit1.text := record_count;
end;

кнопка сохранения в БД:

procedure TForm2.Button1Click(Sender: TObject);
   var
   last_record_count: integer;
   record_count: string;
begin
   SQLQuery1.Active:=False;
   SQLQuery1.SQL.Text:= 'SELECT MAX(record_count) FROM vymoghy';
   SQLQuery1.Active:=True;

   last_record_count := SQLQuery1.Fields[0].AsInteger;
   if last_record_count <> 0 then record_count := IntToStr(last_record_count+1) else record_count := IntToStr(1);

   If Form1.SQLite3Connection1.Connected then
   begin
   SQLQuery1.SQL.Clear;
   SQLQuery1.SQL.Add(Format('insert into vymoghy (record_count, data_vymoghy, borzhnyk, kod_borzhnyka, bank_borzhnyka, mfo_banku, rakhunok, suma, pryznachennja_platezhu) values ("%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s")',[record_count, FormatDateTime('YYYY-MM-DD 00:00:00.000', ZVDateTimePicker1.DateTime), Edit2.Text, Edit3.Text, Edit5.Text, Edit4.Text, Edit6.Text, Edit7.Text, Memo1.Text]));
   SQLQuery1.ExecSQL;
   Form1.SQLTransaction1.CommitRetaining;
   Form1.SQLQuery1.Refresh;
   end;

   Form2.Close;
end;

Несколко экземпляров программы открываются, но ни один не может записать в БД. Если оставить один экземпляр, то он уже сможет записать данные.

Здравствуйте.
После начала использования Вашего конструктора, решил научиться Паскалю с нуля (использую Lazarus).
Пишу программу - копию той, что сделал с помощью конструктора. Всё хорошо, но столкнулся с проблемой блокировки базы данных.
Можете подсказать, как мне можно побороть эту самую блокировку?

12

(13 replies, posted in Russian)

Как вариант, можно поместить внизу формы компонент надпись и по таймеру менять её положение по горизонтали.

Спасибо за отклик.
Разобрался сам.
код

suma := SQLExecute('SELECT suma FROM vymoghy WHERE id = ' + sID);

заменил на

suma := ReplaceStr(SQLExecute('SELECT suma FROM vymoghy WHERE id = '+ sID), ',', '.');

У себя в проекте я сделал возможность создания новой записи на основе уже существующей

procedure MenuClick1;
   var
   sID: string;
   poperednij_record_count: string;
   record_count: string;
   data_vymoghy: string;
   borzhnyk: string;
   kod_borzhnyka: string;
   bank_borzhnyka: string;
   mfo_banku: string;
   rakhunok: string;
   suma: string;
   pryznachennja_platezhu: string;
   dvs: string;
   adresa_dvs: string;
   kod_dvs: string;
   bank_dvs: string;
   mfo_banku_dvs: string;
   rakhunok_dvs: string;
   diljnycja: string;
begin
   sID := IntToStr(frmGholovna.TableGrid_vymoghy.dbItemID);
   if sID = '-1' then Exit;

   poperednij_record_count := SQLExecute('SELECT MAX(record_count) FROM vymoghy');
   if  poperednij_record_count <> '' then record_count := IntToStr(StrToInt(poperednij_record_count) + 1) else record_count := IntToStr(1);
   data_vymoghy := FormatDateTime('yyyy-MM-DD 00:00:00.000', now);
   borzhnyk := ReplaceStr(SQLExecute ('SELECT borzhnyk FROM vymoghy WHERE id = ' + sID), '"', '""');
   kod_borzhnyka := SQLExecute('SELECT kod_borzhnyka FROM vymoghy WHERE id = ' + sID);
   bank_borzhnyka := ReplaceStr(SQLExecute ('SELECT bank_borzhnyka FROM vymoghy WHERE id = ' + sID), '"', '""');
   mfo_banku := SQLExecute('SELECT mfo_banku FROM vymoghy WHERE id = ' + sID);
   rakhunok := SQLExecute('SELECT rakhunok FROM vymoghy WHERE id = ' + sID);
   suma := SQLExecute('SELECT suma FROM vymoghy WHERE id = ' + sID);
   pryznachennja_platezhu := ReplaceStr(SQLExecute ('SELECT pryznachennja_platezhu FROM vymoghy WHERE id = ' + sID), '"', '""');
   dvs := SQLExecute('SELECT dvs FROM vymoghy WHERE id = ' + sID);
   adresa_dvs := SQLExecute ('SELECT adresa_dvs FROM vymoghy WHERE id = ' + sID);
   kod_dvs := SQLExecute('SELECT kod_dvs FROM vymoghy WHERE id = ' + sID);
   bank_dvs := SQLExecute('SELECT bank_dvs FROM vymoghy WHERE id = ' + sID);
   mfo_banku_dvs := SQLExecute('SELECT mfo_banku_dvs FROM vymoghy WHERE id = ' + sID);
   rakhunok_dvs := SQLExecute('SELECT rakhunok_dvs FROM vymoghy WHERE id = ' + sID);
   diljnycja := SQLExecute('SELECT diljnycja FROM vymoghy WHERE id = ' + sID);

   SQLExecute ('INSERT INTO vymoghy (record_count, data_vymoghy, borzhnyk, kod_borzhnyka, bank_borzhnyka, mfo_banku, rakhunok, suma, pryznachennja_platezhu, dvs, adresa_dvs, kod_dvs, bank_dvs, mfo_banku_dvs, rakhunok_dvs, diljnycja) VALUES ("'+record_count+'","'+data_vymoghy+'","'+borzhnyk+'","'+kod_borzhnyka+'","'+bank_borzhnyka+'","'+mfo_banku+'","'+rakhunok+'","'+suma+'","'+pryznachennja_platezhu+'","'+dvs+'","'+adresa_dvs+'","'+kod_dvs+'","'+bank_dvs+'","'+mfo_banku_dvs+'","'+rakhunok_dvs+'","'+diljnycja+'")' );
   frmGholovna.TableGrid_vymoghy.dbUpdate;
   frmGholovna.TableGrid_vymoghy.dbItemID := Last_Insert_id('vymoghy');

   frmGholovna.button_redaghuvaty_vymoghu.Click;
end;

Но существует проблема с дублированием поля сумма (ВЕЩЕСТВ. ЧИСЛО). При открытии записи в соответствующем поле формы просмотра сумма отображается в формате с точкой, например, 145.52 вместо стандартного 145,52. Если нажать кнопку сохранения, то формат преобразуется в обычный - с запятой. А если закрыть форму показа без сохранения, то в гриде сумма 145,52 отображается как 145.

Предлагаю добавить возможность добавления своих кнопок в проекты.
Например, так:
Создаётся png файл, в котором содержится несколько изображений кнопки в различных её состояниях (обычная, нажатая, не активная). Рядом с png файлом размещается xml файл, который содержит описание кнопки (координаты изображений кнопки, соответствующих каждому состоянию).
В папке с проектом создаётся папка "Custom buttons", в которую помещается папка с названием кнопки, содержащая png и xml файлы.
В "Свойства компонента" добавляется пункт "Использовать свою кнопку", по клику на котором вызывается окно, в котором выбирается xml файл.

Как всегда, благодарю.

Возможно ли добавить свой пункт в меню, которое появляется при клике правой кнопкой мышки по гриду?
Я хотел бы добавить пункт: "Создать новую запись на основе существующей", который создаёт копию выделенной записи и открывает окно для редактирования дубликата.

18

(4 replies, posted in Russian)

Я так и сделал.
Просто странно, что потом нельзя сформировать документ.

19

(4 replies, posted in Russian)

У меня в программе через FastReport генерируются платёжные требования. Туда я добавил скрипт, который преобразует сумму числом в сумму прописью.
Если пользователь случайно не указал сумму и нажал кнопку формирования требования, то FastReport выдаёт ошибку: "Could not convert variant of type (UnicodeString) into type (Double)".
Если вернуться в программу и добавить сумму, то сформировать требование уже не возможно - FastReport постоянно выдаёт ошибку: "Access violation at address 00000000. Read of address 00000000".

20

(3 replies, posted in Russian)

Для очистки значения комбобокса:

Form1.ComboBox1.dbItemID := -1;

21

(1 replies, posted in Russian)

Разобрался.

Memo59.text:=DateToPropis (<Report."data_vymoghy">) ;

заменил на

Memo59.text:=DateToPropis (StrToDate(<Report."data_vymoghy">)) ;
function DateToPropis(dDate: Extended):string;
var                                         
 d, m, y : word;
 mess:string;
begin
DecodeDate(dDate,y,m,d);

case m of
 1: mess:='січня';
 2: mess:='лютого';
 3: mess:='березня';
 4: mess:='квітня';
 5: mess:='травня';
 6: mess:='червня';
 7: mess:='липня';
 8: mess:='серпня';
 9: mess:='вересня';
 10: mess:='жовтня';
 11: mess:='листопада';
 12: mess:='грудня';
end;

 Result := IntToStr(d) + ' ' + mess + ' ' + IntToStr(y) + ' року'; 
end;    

begin
     Memo59.text:=DateToPropis (<Report."data_vymoghy">) ;         
end.

Такой код выдаёт ошибку "could not convert variant (UnicodeString) into type (Double)". Судя по всему, он не может использовать формат даты, который получает из БД.
Как это можно исправить?

23

(3 replies, posted in Russian)

Спасибо, попробую.

24

(3 replies, posted in Russian)

Можно ли как-то через скрипт перевести сумму цифрами в сумму прописью на украинском языке?

Спасибо.