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

Уважаемые форумчане, прошу помочь.
У меня есть таблица1. В ней есть строки, которые я копирую кнопкой копировать (кнопка со свойством Показать запись) и к которой я прикрепил скрипт:
if (Action = 'ShowRecord') then  FrmCard.btnSave.dbGeneralTableId := -1; После чего, что надо, правлю и сохраняю, создается новая строка в таблице1 с поправленными параметрами.
На форме, которая открывается из таблицы1, есть не только параметры Edit, DateTimePicker, Combobox, но и TableGrid (назову ее таблица2). В этом случае таблица 2 не копируется, и при открытии она будет пустая. Можно ли как-то сделать так, чтобы и она тоже копировалась со своим содержимым?

Пользователь в моей программе, нажав на кнопку Копировать, начинает редактировать значения, в тч и в TableGrid и после сохранения удивляется, почему в скопированной строке таблицы1 оказываются пустые строки таблицы2 на этой форме, а в той строке, которую он копировал, оказались изменены все строки таблицы2 на как раз те, что изменял для новой записи.

Я понимаю, с чем это связано (он открыл старую запись и правил данные в ней и сохранил под новой записью, но вот таблица2 то так и остается привязанной к старой записи, и она не переносится в новую запись), но не могу придумать как при копировании их тоже скопировать и привязать к новой записи и сразу править.

Чтобы избежать такой проблемы пока обхожусь тем, что строка копируется без возможности внести изменения в запись в таблицу1 и лишь после этого можно открыть скопированную запись и править как вздумается, там будет таблица2 как раз пустая и ее нужно будет заполнить сначала.

Если услуг не много, то можно сделать чекеры для каждой услуги и выставлять галочками те, что нужно отметить.

Может добавить процедуру: при нажатии кнопки сохраняется в невидимое поле DateTimePicker текущее время, дата?
FrmMain.DateTimePicker1.Date:=SQLDateTimeToDateTime(SQLexecute('SELECT datetime (''now'')'));

Через создание Вычисляемого поля-Выражение можно посмотреть описание каждой из функций, которые можно использовать. Также перечень функций можно посмотреть после добавления Скриптов справа (знак f(x)), но там нет такого описания по функции и ее переменных. Думаю полезно будет эту информацию продублировать и там.

Может тогда воспользоваться  if ((SQLexecute('SELECT cast (julianday (date1, "+4 hours") as INT) FROM ... WHERE ...') - SQLexecute('SELECT cast (julianday (date2) as INT) FROM ...')) < '0') then... else...

7

(8 replies, posted in Russian)

sibprogsistem wrote:
procedure Form2_OnShow (Sender: TObject; Action: string);
begin
  Form2.ComboBox1.ItemIndex:=0;
end;

так - как Вы отключили пустое поле, то первое значение будет 0

Спасибо! Действительно так проще, а то я пытался создать этот индекс SQL запросом и не получалось никак.

8

(8 replies, posted in Russian)

Скажите, а какой функцией можно при открытии формы подставить в комбобокс значение по умолчанию?
У меня есть форма, на которой комбобокс. В нем я выбираю один из параметров другой связанной таблицы (Например, Сотрудник, а в комбике я отображаю лишь фамилию).
Пробовал Form1.ComboBox1.dbSQLExecute ('SELECT fieldname, id FROM tablename'); но такой запрос лишь позволяет выбрать в комбике нужный мне вариант, а не сразу сделать за меня выбор, который мне интересен.
Form1.ComboBox1.ItemIndex:=SQLexecute('SELECT 1 FROM tablename'); работает, когда таблица tablename состоит лишь из одного параметра, а если их несколько как у меня Фамилия, Должность и тд, то уже не работает

В примере на главной форме хотел бы показать по умолчанию первую запись. В идеале, где чекбокс=1

9

(5 replies, posted in Russian)

У меня работает при установленных BorderStyle:=bsSizeable и WindowsState:=wsNormal.

10

(2 replies, posted in Russian)

Если имеется в виду, что при редактировании те столбцы, которые заполнялись из комбобокса, открывались также тут в виде комбика, то позволить редактировать/создавать данные в таблице. Свойство Editable и выбрать, что нужно.

sibprogsistem wrote:

дело в том, что когда по Вашему запросу формируется таблица, в нее не отбираются записи, их попросту нет...
то есть id=0....

if SQLexecute('SELECT COUNT(id) FROM status WHERE status.id_card='+ FrmCard_Full.TableGrid1.sqlValue +' ORDER BY date DESC LIMIT 1') then
    FrmCard.DateTimePicker2.DateTime:=SQLDateTimeToDateTime(SQLexecute('SELECT date(ifnull(date,"2020-07-07")) FROM status WHERE status.id_card='+ FrmCard_Full.TableGrid1.sqlValue +' ORDER BY date DESC LIMIT 1')) else
    showmessage('пусто');

Понял. Спасибо за помощь!
Думал, что и в случае, когда NULL возвращается, и когда id=0, будет одинаково работать функция IFNULL, а  оказывается нет.
Поправил для себя вот так:

if SQLexecute('SELECT COUNT(id) FROM status WHERE status.id_card='+ FrmCard_Full.TableGrid1.sqlValue +' ORDER BY date DESC LIMIT 1')
then FrmCard.DateTimePicker2.DateTime:=SQLDateTimeToDateTime(SQLexecute('SELECT date(date) FROM status WHERE status.id_card='+ FrmCard_Full.TableGrid1.sqlValue +' ORDER BY date DESC LIMIT 1'))
else FrmCard.DateTimePicker2.DateTime:=SQLDateTimeToDateTime(SQLexecute('SELECT date("2019-07-07")'));

Не сработало. На втором Card не подставляет дату при пустом Status.
Функцию Date я использовал, чтобы оставить от даты/времени только дату.

Столкнулся со следующей ситуацией в своем примере.
Ранее я хотел получить дату последнего статуса прибора Card. Получил.
Но если у меня прибор был только занесен в базу и еще нет у него статусов. В этом случае я получаю ошибку при формировании этой даты.
Чтобы избавиться от этого, решил, что надо внести дополнительную проверку функцией ifnull, но у меня она не работает.
Вот такой запрос работает: FrmCard.DateTimePicker2.Date:=SQLDateTimeToDateTime(SQLexecute('SELECT date (ifnull(''2020-05-25'',''2019-01-31''))'));
Или FrmCard.Edit2.Text:=SQLexecute('SELECT date(ifnull(''2020-05-25'', "2019-01-31"))');
А вот такой нет: FrmCard.DateTimePicker2.Date:=SQLDateTimeToDateTime(SQLexecute('SELECT date(ifnull(date,''2019-01-31'')) FROM status WHERE status.id_card='+ FrmCard_Full.TableGrid1.sqlValue +' ORDER BY date DESC LIMIT 1'));
Или FrmCard.Edit2.Text:=SQLexecute('SELECT date(ifnull(date, "2019-01-31")) FROM status WHERE status.id_card='+ FrmCard_Full.TableGrid1.sqlValue +' ORDER BY date DESC LIMIT 1');

В первом случая я выбираю из 2-х дат, во втором случае из запроса и даты.
Скажите, что неверно в синтаксисе использования ifnull?
В примере демонстрация для Card под именем 2.

14

(43 replies, posted in Russian)

Вопрос снят.Решил такой записью: FrmCard.ComboBox2.ItemIndex:=SQLexecute('SELECT name_status.id FROM...
При таком запросе в комбике сразу отображается Текущий статус из вообще всех возможных статусов

15

(43 replies, posted in Russian)

В прошлом примере была ошибка, потому сделал дубликат комбобокса, значение которого и хотелось бы использовать на форме как текущий статус.

Может просто кто знает как с помощью скрипта выбрать значение из одной сущности и этот выбор отобразить в форме на комбобоксе?

Например. В одной форме я задаю варианты значений Статус (1,2...). А на другой форме я в комбике уже отображаю этот самый выбор из 1,2... по условиям, что прописываю в скрипте.

16

(43 replies, posted in Russian)

Понял, что вы сделали.
Я имел в виду показывать в поиске не все записи с этим статусом, а лишь тот Card, у которого запись с таким статусом последняя.
Потому я решил создать дополнительный параметр - Текущий статус, по которому уже и фильтровать Card в поиске, но не знаю как присвоить определенный статус комбобоксу, чтобы его потом на форме Card сохранить, а уже на форме Card_Full использовать в качестве комбобокса для поиска.

17

(43 replies, posted in Russian)

А что именно вы поменяли? Вроде отличие только в закомментированной части скрипта, но она не сработала после разкомментирования.

Да, создается сама связь в другом месте, а в этой форме я хотел лишь отобразить выбор с другой формы.

18

(43 replies, posted in Russian)

Решил отобразить в форме Card последний по дате статус прибора (name_status.name). Сделал отображение в Edit2 FrmCard. Но тут задумался - мне же нужно потом по этому параметру осуществлять поиск по приборам Card у кого какой текущий статус и они могут быть разные, а выбираются они из комбобокса, который хранится в таблице name_status. Вывел его на той же форме Комбобокс2.

Как мне в таком случае быть, чтобы организовать поиск?
Как я понимаю - 1) попробовать сохранять не в Edit, а в том самом комбобоксе, что отвечает за выбор статусов, но что-то у меня это не сработало с моим запросом.
2) Сохранять в Edit, но потом как-то в поиске придумать комбобокс и к нему как-то привязать компонент Edit - тоже не знаю как
3) Искать по компоненту Edit, заполняя вручную статусы, без возможности выбора. Могу, но как-то это будет смотреться криво.
Идеально конечно был бы первый вариант, но как его реализовать я не знаю. Прошу помощи в этом.

Спасибо! "Enabled". что надо.
Я как раз наоборот с Edit ушел, т.к. хочу потом этот параметр в поиске применить, а использовать Edit в поиске дат не очень хочу. Точнее не знаю как это будет выглядеть, потому по-старинке использую компонент дат.

Может кто знает как можно запретить редактирование компонента DateTimePicker? У Edit есть свойство Read only, а у DateTimePicker такого не наблюдаю. Возможно можно как-то можно перекрыть эту дату компонентом, который сделать прозрачным? Но тоже не могу найти такого компонента для этих целей.

21

(43 replies, posted in Russian)

Спасибо! Точно, этой функции в списке вариантов не увидел smile

22

(43 replies, posted in Russian)

А можно как-то вычисленную дату записать не в компонент Edit, а в DateTimePicker? Хотел это реализовать, чтобы при сохранении полученной даты в БД, по ней потом поиск вести через компонент DateTimePicker.

Написал так:
Var
i: string;
begin
i:=SQLexecute(SQLexecute ('SELECT date(date, "+'+ FrmCard.ComboBox1.Text +' month") FROM status WHERE id='+FrmCard.TableGrid1.sqlValue)');
FrmCard.DateTimePicker1.Date:=StrToDate('i');
end;
Пишет, что ошибка в неверном формате даты.

23

(43 replies, posted in Russian)

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

24

(43 replies, posted in Russian)

Спасибо, sibprogsistem! Работает.
Скажите, а как в этом случае показать в таблице на форме FrmCard_Full после названия card, to_interval, полученную дату? Я только знаю способ через вычисляемое поле отобразить нужное мне значение, но с таким текстом как:
(
SELECT date(date, '+ to_interval.value month')
FROM status
LEFT OUTER JOIN organization ON status.id_organization=organization.id
LEFT OUTER JOIN to_interval ON card.id_to_interval=to_interval.id
WHERE organization.id_name_status=1
AND status.id_card=card.id
ORDER BY date DESC LIMIT 1

оно не работает.
Я вижу тут два варианта - или поправить вычисл. поле, так чтобы оно заработало, либо видимо использовать SQL запрос, чтобы добавить столбец со вычисленными датами в таблицу, но этого я не умею.

25

(43 replies, posted in Russian)

На базе прошлой задачи возникла задача сложения полученной отфильтрованной даты со значением to_inerval.value (целое число), что представляет собою количество месяцев.
Физический же смысл следующий - оборудование из таблицы card имеет статус "Проведено техническое обслуживание" (name status) такого-то числа (date) (эту дату получили с помощью скрипта ранее). Чтобы получить следующую дату проведения технического обслуживания, нужно сложить интервал тех.обсл. (to_interval.value) и последнюю дату проведенного тех.обсл..
Пробовал использовать функции date (..., '+to_interval.value months') и strftime  ('%Y-%m-%d',..., '+to_interval.value months'), но не работает ни вычисляемое поле, ни скрипт. Если писать в скобках вместо  '+to_interval.value months', например, '+12 months', то все работает, а если значение из таблицы, то нет.

FrmCard.Edit2.Text:=SQLexecute('SELECT date (date, ''+to_interval.value months'') FROM status LEFT OUTER JOIN organization ON status.id_organization=organization.id LEFT OUTER JOIN to_interval ON card.id_to_interval=to_interval.id WHERE organization.id_name_status=1 AND status.id_card='+ FrmCard_Full.TableGrid1.sqlValue +' ORDER BY date DESC LIMIT 1');
Скажите, в чем моя ошибка использования этих функций?