Форум программистов, компьютерный форум, киберфорум
Delphi: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
394 / 194 / 48
Регистрация: 11.07.2013
Сообщений: 1,211

"Висяк" при попытке вывести на печать данных сразу же после их отправки в БД

20.04.2024, 21:28. Показов 1158. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Чувствую, что где-то что-то делаю не правильно.
Delphi
1
2
3
4
5
...
  SQLTransaction1.Commit; // Совершить транзакцию (зафиксировать изменения).
  Form4.LoadDataReport(Tpu, Num1s); // Загрузить данные в отчёт.
  Form4.XPrint(); // Вывести на XPrinter.
...
Такое впечатление, что SQLTransaction1.Commit отправлен и тут же у меня идёт запрос к тому, что я отправил, а база ещё эти данные не записала. Получается какой-то конфликт.
Вот код записи в БД:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Убыл (записать в таблицу данные о убытии и проверка за счт "RETURNING *").
procedure TDataModule2.Departed();
var
  S: String;
  n: Integer;
  Year, Month, Day: Word;
  Huar, Min, Sec, MSec: Word;
  R: String; // Режим (А -автомат, Р - ручной, Рв - вес ручной.
begin
  if not DataModule2.PQConnection1.Connected then begin
    MessageDlg('CarWeights v02TA', 'Нет связи с сервером. Перезагрузите БД. '+
    'Обратитесь к администратору и доложите руководителю о весе убывшено '+
    'автомобиля.', mtWarning,[mbOK], 0);
    exit;
  end;
  if Form6.f6 then begin
    if INI.FHand then
      R:='Рв'
    else
     R:='Р';
  end else
    R:='А';
  DecodeDate(Tpu, Year, Month, Day);
  DecodeTime(Tpu, Huar, Min, Sec, MSec);
  Tpu:=EncodeDate(Year, Month, Day);
  Tpu:=Tpu+EncodeTime(Huar, Min, 0, 0);
  S:=FloatToStr(Tpu); // // Дата и время прибытия.
  n:=Pos(',',S);
  if n>0 then S[n]:='.';
  SQLQuery1.Active:=false;
  SQLQuery1.SQL.Clear;
  SQLQuery1.SQL.Add('UPDATE '+INI.Tab+' SET '+
    'nU='+S+ // Дата и время убытыия в числовом формате.
    ', sDatU='+chr(39)+ FormatDateTime('ddddd',Tpu)+chr(39)+ // Дата убытия.
    ', sTimU='+chr(39)+FormatDateTime('t',Tpu)+chr(39)+ // Время убытия.
    ', fVesU='+Vpu+ // Вес при убитии.
    ', sVnU='+chr(39)+INI.Num+chr(39)+  // Номер весов.
    ', sRejU='+chr(39)+R+chr(39)+  // Режим.
    ', sOperU='+chr(39)+Oper+chr(39)+  // Оператор.
    ', fTara=CASE WHEN fVesP>='+Vpu+' THEN '+Vpu+' ELSE fVesP END'+ // Тара.
    ', fBrut=CASE WHEN fVesP>='+Vpu+' THEN fVesP ELSE '+Vpu+' END'+ // БРУТТО.
    ', fNetP=CASE WHEN fVesP>='+Vpu+' THEN fVesP-'+Vpu+' ELSE 0 END'+ // НЕТТО пр.
    ', fNetU=CASE WHEN fVesP>='+Vpu+' THEN 0 ELSE '+Vpu+'-fVesP END'+ // НЕТТО уб.
    ' WHERE '+
    '(sNum1='+chr(39)+Num1s+chr(39)+' OR sNum2='+chr(39)+Num1s+chr(39)+' '+
    'OR sNum1='+chr(39)+Num2s+chr(39)+' OR sNum2='+chr(39)+Num2s+chr(39)+') '+
    'AND nU=0 RETURNING *');
  try
    //--------------- Так рекомендуется осуществлять транзакции --------------
    if SQLTransaction1.Active then // Прервать транзакцию, если она активна.
      SQLTransaction1.EndTransaction;
    SQLTransaction1.Options:=[stoExplicitStart]; // Затребовать явный запуск
    // транзакции с помощью TSQLQuery.
    SQLTransaction1.StartTransaction; // Начать новый блок транзакции.
    SQLQuery1.Open; // Отправить запрос на сервер.
    if SQLQuery1.RecordCount = 0 then begin
      MessageDlg('CarWeights v02TA', 'Отсутствует информация о прибытии '+
      'автомобиля. Обратитесь к администратору и доложите руководителю о '+
      'весе убывающего автомобиля.'+#13+'Если же номера автомобиля "'+Num1s+
      '" и "'+Num2s+'", прочитанные камерами, содержат ошибку или при прибытии'+
      ' выла допущена ошибка в определении номеров, то исправьте номера '+
      'в ручном режиме (Управление/Исправить номер авто.).',
      mtWarning,[mbOK], 0);
        DataModule1.Rej:=10;
    end else begin
      SQLTransaction1.Commit; // Совершить транзакцию (зафиксировать изменения).
      if INI.Print then begin // Вывести чек на печать.
        Form4.LoadDataReport(Tpu, Num1s); // Загрузить данные в отчёт.
        Form4.XPrint();// Вывести на XPrinter.
      end;
    end;
    SQLTransaction1.Options:=[]; // Очистить опции.
    SQLQuery1.Close;
    ShowData(); // Показать данные.
  except
    MessageDlg('CarWeights v02TA', 'Првреждена база данных. Обратитесь к '+
    'администратору и доложите руководителю о весе убывающего '+
    'автомобиля.', mtError,[mbOK], 0);
  end;
end;
Вот код вывода на печать:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
// Загрузить данные в отчёт.
procedure TForm4.LoadDataReport(t: TDateTime; Num: String);
var
  S, St, M, Mp: String;
  Year, Month, Day: Word;
  Huar, Min, Sec, MSec: Word;
  n, x, y: Integer;
  sz: TSize;
  col: Integer;
  f, fp: Single;
begin
  DecodeDate(t, Year, Month, Day); // Показать данные в основном окне.
  DecodeTime(t, Huar, Min, Sec, MSec);
  S:=FloatToStr(EncodeDate(Year, Month, Day)+EncodeTime(Huar, Min, 0, 0));
  n:=Pos(',',S);
  if n>0 then
    S[n]:='.';
  DataModule2.Filtr:=' WHERE (sNum1='+chr(39)+Num+chr(39)+
  'OR sNum2='+chr(39)+Num+chr(39)+') AND nU='+S;
  DataModule2.ShowData();
  Image1.Canvas.FillRect(0, 0, Image1.Width, Image1.Height); // Очистить чек.
  x:=(Image1.Width-ImageList1.Width) div 2; // Логотип.
  y:=20;
  ImageList1.Draw(Image1.Canvas, x, y, 0, true);
  Image1.Canvas.Font.Style:=[fsBold];  // Заголовок.
  Image1.Canvas.Font.Size:=12;
  S:=INI.Name; // Название организации.
  sz:=Image1.Canvas.TextExtent(S);
  x:=(Image1.Width-sz.cx) div 2;
  y:=y+ImageList1.Height+5;
  Image1.Canvas.TextOut(x, y, S);
  Image1.Canvas.Font.Style:=[];  // Параметры других строк.
  Image1.Canvas.Font.Size:=10;
  try
    Form1.RxDBGrid1.DataSource.DataSet.First; // Курсор в начало БД.
    for col:=0 to Form1.RxDBGrid1.DataSource.DataSet.FieldCount-1 do begin
      M:=Form1.RxDBGrid1.DataSource.DataSet.Fields[col].AsString;
      for n:=Length(M) downto 1 do  begin  // Удалить пробелы в конце строки.
        if M[n]=' ' then
          Delete(M, n, 1)
        else
          break;
      end;
      if(M<>'')and((col=5)or(col=11)or(col=15)or(col=16)or(col=17)or(col=18))
      then begin
        f:=StrToFloat(M);
        f:=RoundTo(f, DataModule1.Idot);
        M:=FormatFloat(DataModule1.Sdot, f);
      end;
      case col of
        0: begin
          S:='RFID:';
          y:=y+sz.cy+5;
          Image1.Canvas.TextOut(20, y, S);
          sz:=Image1.Canvas.TextExtent(M);
          Image1.Canvas.TextOut(206-sz.cx, y, M);
          sz:=Image1.Canvas.TextExtent(S);
          y:=y+sz.cy+2;
        end;
        1: begin
          S:='№1 авто.:';
          Image1.Canvas.TextOut(20, y, S);
          sz:=Image1.Canvas.TextExtent(M);
          Image1.Canvas.TextOut(206-sz.cx, y, M);
          sz:=Image1.Canvas.TextExtent(S);
          y:=y+sz.cy+2;
        end;
        2: begin
          S:='№2 авто.:';
          Image1.Canvas.TextOut(20, y, S);
          sz:=Image1.Canvas.TextExtent(M);
          Image1.Canvas.TextOut(206-sz.cx, y, M);
          sz:=Image1.Canvas.TextExtent(S);
          y:=y+sz.cy+2;
        end;
        3: St:=M; // Дата прибытия.
        4: begin
          S:='Прибыл:';
          Image1.Canvas.TextOut(20, y, S);
          M:=St+' '+M;
          sz:=Image1.Canvas.TextExtent(M);
          Image1.Canvas.TextOut(206-sz.cx, y, M);
          sz:=Image1.Canvas.TextExtent(S);
          y:=y+sz.cy+2;
        end;
        5: begin
          S:='Вес (кг):';
          Image1.Canvas.TextOut(20, y, S);
          sz:=Image1.Canvas.TextExtent(M);
          Image1.Canvas.TextOut(206-sz.cx, y, M);
          sz:=Image1.Canvas.TextExtent(S);
          y:=y+sz.cy+2;
        end;
        9: St:=M; // Дата уьытия.
        10: begin
          S:='Убыл:';
          Image1.Canvas.TextOut(20, y, S);
          M:=St+' '+M;
          sz:=Image1.Canvas.TextExtent(M);
          Image1.Canvas.TextOut(206-sz.cx, y, M);
          sz:=Image1.Canvas.TextExtent(S);
          y:=y+sz.cy+2;
        end;
        11: begin
          S:='Вес (кг):';
          Image1.Canvas.TextOut(20, y, S);
          sz:=Image1.Canvas.TextExtent(M);
          Image1.Canvas.TextOut(206-sz.cx, y, M);
          sz:=Image1.Canvas.TextExtent(S);
          y:=y+sz.cy+2;
        end;
        15: begin
          S:='Тара (кг):';
          Image1.Canvas.TextOut(20, y, S);
          sz:=Image1.Canvas.TextExtent(M);
          Image1.Canvas.TextOut(206-sz.cx, y, M);
          sz:=Image1.Canvas.TextExtent(S);
          y:=y+sz.cy+2;
        end;
        16: begin
          S:='БРУТТО (кг):';
          Image1.Canvas.TextOut(20, y, S);
          sz:=Image1.Canvas.TextExtent(M);
          Image1.Canvas.TextOut(206-sz.cx, y, M);
          sz:=Image1.Canvas.TextExtent(S);
          y:=y+sz.cy+2;
        end;
        17: begin  // Приход.
          fp:=f;
          Mp:=M;
        end;
        18: begin // Расход.
          S:='НЕТТО (кг):';
          Image1.Canvas.TextOut(20, y, S);
          if fp>f then begin
            M:=Mp;
            St:='Приход';
          end else
            St:='Расход';
          sz:=Image1.Canvas.TextExtent(M);
          Image1.Canvas.TextOut(206-sz.cx, y, M);
          sz:=Image1.Canvas.TextExtent(S);
          y:=y+sz.cy+2;
          Image1.Canvas.Font.Style:=[fsBold];
          sz:=Image1.Canvas.TextExtent(St);
          x:=(Image1.Width-sz.cx) div 2;
          Image1.Canvas.TextOut(x, y, St);
          Image1.Canvas.Font.Style:=[];
          y:=y+sz.cy+2;
        end;
      end;
    end;
    S:='Опер.: '+DataModule2.Oper;;
    Image1.Canvas.TextOut(20, y, S);
    sz:=Image1.Canvas.TextExtent(S);
    y:=y+sz.cy+2;
    S:=FormatDateTime('dd mmmm yyyy - hh:nn', Now);
    sz:=Image1.Canvas.TextExtent(S);
    x:=(Image1.Width-sz.cx) div 2;
    Image1.Canvas.TextOut(x, y, S);
  except
    MessageDlg('CarWeights v02TA', 'Данные в базе данных не обнаружены.',
      mtWarning,[mbOK], 0);
  end;
end;
// Вывести на XPrinter.
procedure TForm4.XPrint();
var
  MyPr: TPrinter;
  x, y: Integer;
  RR: TRect;
begin
  Printer.Title := 'Чек';  // Имя файла, отправленного на печать.
//---------------------------------
// Добавить новой зависимости через Проект -> Инспектор проекта ->
// -> Добавить новую зависимость -> Printer4Lazarus -> Ok
//---------------------------------
  MyPr:=Printer;  // Получаем доступ к глобальному объекту Printer.
  MyPr.SetPrinter('*');
  try
    MyPr:=Printer;  // Получаем доступ к глобальному объекту Printer.
    // Коэффициенты масштабирования изображения.
    x:= GetDeviceCaps(MyPr.Canvas.Handle, logPixelsX) div PixelsPerInch;
    y:= GetDeviceCaps(MyPr.Canvas.Handle, logPixelsY) div PixelsPerInch;
    MyPr.BeginDoc; // Начало печати
    // Отрисовка нашего изображения на виртуальной канве принтера.
    RR:=Rect(0, 0, Image1.Picture.Width * x, Image1.Picture.Height * y);
    MyPr.Canvas.StretchDraw(RR, Image1.Picture.Bitmap);
  finally
    MyPr.EndDoc; // Конец печати
  end;
end;
Если вывожу данные на печать через какое-то время (несколько секунд), то проблем нет.
Можно ли как-то узнать, что транзакция завершилась и можно производить чтение из БД? Как правильно поступить?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
20.04.2024, 21:28
Ответы с готовыми решениями:

как вывести модальное окно после отправки данных на сервер
Всем привет. Есть форма, которая отправляет методом post данные на сервер. Там эти данные отправляются на маил. Потом возвращаемся на...

Как вывести модальное окно после отправки данных на сервер
Всем привет. Есть форма, которая отправляет методом post данные на сервер. Там эти данные отправляются на маил. Потом возвращаемся на...

Удаление письма в Outlook сразу же после отправки
Форум, привет! Средством VBA формируется письмо и отправляется через Outlook. Подскажите, возможно ли отправленное письмо сразу же...

10
 Аватар для Аватар
5393 / 1465 / 513
Регистрация: 31.05.2012
Сообщений: 5,153
21.04.2024, 10:58
чего это update методом open на сервер отправляешь? то для селекта. поищи метод execsql или что-то в этом духе, забыл уже )
0
Айлурофил
 Аватар для Massaraksh7
514 / 447 / 112
Регистрация: 27.05.2017
Сообщений: 2,704
Записей в блоге: 5
21.04.2024, 17:23
Цитата Сообщение от Аватар Посмотреть сообщение
поищи метод execsql
Execsql не возвращает значение по RETURNING
0
394 / 194 / 48
Регистрация: 11.07.2013
Сообщений: 1,211
21.04.2024, 18:04  [ТС]
Переставил немного в другое место. Зависания прекратились.
Delphi
1
2
3
4
5
    SQLTransaction1.Commit; 
    SQLTransaction1.Options:=[]; 
    SQLQuery1.Close;
    Form4.LoadDataReport(Tpu, Num1s); 
    Form4.XPrint();
Однако, не могу понять, почему принтер "долго думает" (секунд 5) перед тем, как начинает печатать.
0
Айлурофил
 Аватар для Massaraksh7
514 / 447 / 112
Регистрация: 27.05.2017
Сообщений: 2,704
Записей в блоге: 5
22.04.2024, 02:55
Цитата Сообщение от shyub Посмотреть сообщение
if SQLQuery1.RecordCount = 0 then begin
Вот по этому условию я не вижу ни коммита, ни роллбэка. Это неправильно.
0
394 / 194 / 48
Регистрация: 11.07.2013
Сообщений: 1,211
22.04.2024, 06:24  [ТС]
Цитата Сообщение от Massaraksh7 Посмотреть сообщение
f SQLQuery1.RecordCount = 0 then begin
Вот так будет правильно?
Delphi
1
2
3
4
5
6
7
8
9
10
    ........
    SQLTransaction1.StartTransaction; // Начать новый блок транзакции.
    SQLQuery1.Open; // Отправить запрос на сервер.
    if SQLQuery1.RecordCount = 0 then begin
      SQLTransaction1.Rollback;
      MessageDlg('CarWeights v02TA', 'Отсутствует информация о прибытии '+
      ........
    end else begin
      SQLTransaction1.Commit; 
      .......
Т.е. если данные о прибытии отсутствуют, то отменить танзакцию (SQLTransaction1.Rollback).
0
184 / 37 / 8
Регистрация: 14.04.2019
Сообщений: 238
22.04.2024, 07:48
Не следует использовать RecordCount. В SQL- серверах он всегда равен 0
0
 Аватар для Аватар
5393 / 1465 / 513
Регистрация: 31.05.2012
Сообщений: 5,153
22.04.2024, 09:04
Цитата Сообщение от DedFriend Посмотреть сообщение
В SQL- серверах он всегда равен 0
ни чего подобного. он равен количеству строк на клиенте, другое дело что с сервера еще не все строки могут быть переданы на этот момент. поэтому с ним осторожней. в данном случае указатель переместить на конец набора данных что бы наверняка
0
Айлурофил
 Аватар для Massaraksh7
514 / 447 / 112
Регистрация: 27.05.2017
Сообщений: 2,704
Записей в блоге: 5
22.04.2024, 09:30
Цитата Сообщение от shyub Посмотреть сообщение
Вот так будет правильно?
Да, транзакция должна быть как-то завершена в любом случае.
1
 Аватар для Аватар
5393 / 1465 / 513
Регистрация: 31.05.2012
Сообщений: 5,153
22.04.2024, 09:52
там еще непонятки как транзакция откатится в исключении если оно подымится на open
0
 Аватар для krapotkin
6849 / 4676 / 1464
Регистрация: 14.04.2014
Сообщений: 20,671
Записей в блоге: 21
22.04.2024, 11:02
Цитата Сообщение от shyub Посмотреть сообщение
Удалить пробелы в конце строки.
s := trim(s)

Добавлено через 7 минут
одно из простых правил программирования - don't repeat code
у вас один и тот же кусок повторяется 10 раз
почему не сделать процедуру ?
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
   procedure PrintOut(ACaption, AText);
   begin
      Image1.Canvas.TextOut(20, y, ACaption);
      sz:=Image1.Canvas.TextExtent(AText);
      Image1.Canvas.TextOut(206-sz.cx, y, AText);
      sz:=Image1.Canvas.TextExtent(ACaption);
      y:=y+sz.cy+2;
    end;
....
 10: begin
   PrintOut('Убыл:', St+' '+M);
  end;
и вам сложнее ошибиться, и нам (и вообще тем, кто после вас придет) проще разбирать


ну и про полезность использования параметров в запросах
https://www.cyberforum.ru/blog... g5254.html


в целом использование update returning нужно сначала отдельно протестировать на отдельном простейшем примере для конкретно вашего сервера и ваших компонент доступа.
в принципе, это может работать, но гарантии нет.
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
22.04.2024, 11:02
Помогаю со студенческими работами здесь

Можно ли делать переадресацию функцией header сразу после отправки формы ?
Добрый день! у меня в коде есть такой момент: в форме есть action c маршрутом. Для маршрута есть контролер - функция, в которой я...

В таблице значений после отправки на печать меняются значения
Добрый день. Всю голову сломал. Есть таблица значений. Выводим её на печать. (появляется окно предварительного просмотра) = Всё...

Выходит ошибка при попытке отправки файла по TCP
using System; using System.IO; using System.Net; using System.Net.Sockets; using System.Windows.Forms; using System.Text; ...

Ошибка аутентификации при попытке отправки письма из собственной конфигурации 1С
Здравствуйте. Из собственной конфигурации 1С 8.3 (тек. версия платформы 8.3.16.1063) пытаюсь отправить письмо через почтовый сервер (сом...

При попытке зайти в биос ноутбук сразу же перезагружается
Здравствуйте На ноутбуке Lenovo ideapad-110 15acl при попытке зайти в БИОС (fn+f2) он сразу же перезагружается. То есть: появляется...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 31.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
Автоматическое создание документа при проведении другого документа
Maks 29.03.2026
Реализация из решения ниже выполнена на нетиповых документах, разработанных в конфигурации КА2. Есть нетиповой документ "ЗаявкаНаРемонтСпецтехники" и нетиповой документ "ПланированиеСпецтехники". В. . .
Настройка движения справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru