1,151

(12 replies, posted in Russian)

agatlogic101 wrote:

Оу, с PageControl вариант, а возможно скрыть скриптом выбор вкладок? Что бы малых прямоугольников "Вкладка1" "Вкладка2" не было видно при запуске формы?

Процедура скрывает все ярлыки закладок у многостраничника:

procedure HideTabs( APageControl: TdbPageControl );
// скрыть закладки
var
  i: integer;
begin
  for i := 0 to APageControl.PageCount - 1 do
  begin
    APageControl.Pages[i].TabVisible := false;
  end;
end;

Пример использования:

HideTabs( Form1.PageControl1 );
agatlogic101 wrote:

В больших проектах, когда много форм, естественно всё долго грузится. Есть ли возможность отключать/заморозить некоторые формы, которые в данный момент при работе не нужны, что бы они не влияли на сохранение и загрузку. Что даст ускорение при работе с определённой частью программы. Иначе приходится создавать подпрограмму, в ней тестировать то, что нужно добавить, и после уже вручную копировать таблицы, формы, скрипт...
PS. С точки зрения пользователя, было бы 2 чекбокса на форме, вместо одного. 1 как и раньше скрывает форму в программе что бы она не мешалась, а вторая замораживает


Как показали мои наблюдения, задержку вызывает не создание форм, а выгребание данных для компонентов на форме.
И, если для таблиц данные выгребаются в момент открытия формы, то для комбиков - при подключении к БД. Для MySQL это можно регулировать, выполняя команду UpdateDatabase() в нужное время (например, после отображения формы-заставки).

      // вызываем автозаполение ComboBox-ов, но по отдельности для каждой таблицы
      tmpFileName := ExtractFileDir(ParamStr(0))+'\tables.ini';
      tmpTablesIni := TMemIniFile.Create( tmpFileName ); // для работы с этим файлом использовать TMemIniFile - он нормально работает с Unicode
      tmpList := TStringList.Create;
      try
        tmpTablesIni.ReadSections( tmpList );
        for i := 0 to tmpList.Count - 1 do
        begin
          ConnectionProgress( i/tmpList.Count, tmpList.Strings[i] ); // отобразить название таблицы
          Application.ProcessMessages;
          Sleep(100); // задержка, чтобы видно было ))
          UpdateDatabase(tmpList.Strings[i]);
        end;
      finally
        tmpList.Free;
        tmpTablesIni.Free;
        ConnectionProgress(-1,' ');
        // звуковое подтверждение окончания загрузки
        tmpSoundFileName := copy(ParamStr(0),1,length(ParamStr(0))-4)+'.wav';
        // можно ставить любой файл, а если надоест, то удалить его совсем
        if FileExists(tmpSoundFileName) then
          PlaySound( tmpSoundFileName );
      end;


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


P.S. Долгое время создания именно формы бывает, если на ней находится много графических элементов. Для себя я эту проблему решил созданием и загрузкой графического контента из базы после запуска программы, в момент отображения заставки. Это позволяет реализовать богатый UI: в примере форма содержит больше сотни графических элементов (кнопки с тремя состояниям на базе TdbImage)

http://myvisualdatabase.com/forum/misc.php?action=pun_attachment&item=6310&download=0

sibprogsistem wrote:
procedure Form1_Button1_OnClick (Sender: TObject; var Cancel: boolean);
var
i:integer;
begin
  for i:=0 to Form1.TableGrid1.RowCount-1 do begin
      Form1.Memo1.Lines.Add(SQLExecute('SELECT id FROM qq WHERE id='+IntToStr(Form1.TableGrid1.dbIndexToID(i))));
      end;
end;

Зачем ID из базы тянуть? можно проще:


procedure Form1_Button1_OnClick (Sender: TObject; var Cancel: boolean);
var
  i:integer;
begin
  for i:=0 to Form1.TableGrid1.RowCount-1 do
    Form1.Memo1.Lines.Add( IntToStr(Form1.TableGrid1.dbIndexToID(i) );
end;

1,154

(2 replies, posted in Russian)

А зачем вы проверяете Parent у Sender?  Или вы используете обработчик MouseDown  не только для этих меток, но и для других?
Да и проверка

 if (TLabel) then

какая-то странная.То есть она ничего не проверяет )))  Для чего она нужна?

Если procedure MouseDown() используется только у меток, созданных программно, то никакие проверки не нужны:

procedure MouseDown(Sender: Tobject);
begin
    ShowMessage(TLabel(sender).Caption);
end;

Если вам нужно, чтобы клик срабатывал только для меток на панели (при условии, что обработчик назначен ещё каким-то меткам и другим компонентам), то так:

procedure MouseDown(Sender: Tobject);
var
  LPanel: TPanel;
begin
  LPanel := nil;
  if sender is TLabel then
  begin
    if TLabel(sender).Parent is TPanel then
      LPanel := TPanel(TLabel(sender).Parent);
      if  LPanel <> nil  then
      begin
        ShowMessage(TLabel(sender).Caption);
      end;
  end;
end;

1,155

(15 replies, posted in Russian)

vovka3003 wrote:

Можно и так, но визуально лучше воспринимается цепочка (имхо).

Пожалуй, соглашусь: две отдельные проверки - это надежней, так как не стоит полностью полагаться на неявные соглашения - в какой-то момент их могут поменять, и код перестанет работать.

abc52 wrote:

Ув.  Дмитрий !   


       У таблицы и полей есть названия, а в скриптах приходится

    обращаться к ячейкам через Form1.TableGrid1,Cells[c,r].


  А ведь самое простое Tb.Fd [row] - таблица.поле[строка]
 
  упростило бы написание скриптов значительно избавив от

    зависимости от ячеек,колонок при изменении порядка полей.


  Tb.Fd   встречается при настройке TableGrid1, а в скрипте

   как это использовать ?

TableGrid используется не только для отображения табличных данных, это очень мощный элемент интерфейса, раскрывающий свой потенциал через скрипты. В тексте скриптов используйте константы: если добавилась колонка, то достаточно изменить значение константы:

const
  DATA_COL = 1;
...
frmMain.tgrData.Cells[ DATA_COL, y ]

1,157

(15 replies, posted in Russian)

sibprogsistem wrote:
vovka3003 wrote:

"And" = "then if"

в смысле заменить на then  if,  с начало получаем label а потом проверяем на parent?

Обычно по умолчанию включена оптимизация выполнения условий IF <выражение> AND <выражение>  - если первое выражение в условии равно FALSE, то второе не будет проверяться. Поэтому можно оставить так как есть.

1,158

(3 replies, posted in General)

Set property HeaderStyle = hsFlatBorder and use this code:

procedure frmMain_TableGrid1_OnChange (Sender: TObject);
begin
  frmMain.TableGrid1.Columns[0].Header.Color := clRed;
end;

You can change only header background color, header font color = table font color

1,159

(2 replies, posted in Script)

use SetLength( <DinamicArray>, <NewSize> ), this procedure keep data in array if it possible

var
  DA: array of string;
begin
...
  SetLength( DA, 10);
...
  SetLength( DA, 50);

Было бы логично, если бы function DayOfWeek() зависела от системных настроек:

http://myvisualdatabase.com/forum/misc.php?action=pun_attachment&amp;item=6214&amp;download=0

к сожалению, сейчас это не так

1,161

(187 replies, posted in General)

teco049 wrote:

K245

In the meantime, you can use the standard DLL mechanism to expand functionality.


Do you have an example how to use the standard DLL mechanism from MyVisualDatabase?

Use DynamicWrapperX -

http://myvisualdatabase.com/forum/viewtopic.php?id=4800

function DLL:variant;
    var DW:variant;
begin
    DW := CreateOleObject('DynamicWrapperX');
    DW.Register('kernel32.dll', 'Beep', 'i=uu');
    DW.Register('user32.dll', 'GetSystemMetrics', 'i=l','r=l');
    // Функции вашей DLL
    result := dw;
    DW := nil;
end;

procedure Form1_Button1_OnClick (Sender: TObject; var Cancel: boolean);
 var i : integer;
begin
  dll.Beep(800,1000);
  ShowMessage('Монитор: ' +
  IntToStr(dll.GetSystemMetrics(0))+ 'x' +
  IntToStr(dll.GetSystemMetrics(1)));
end;

begin
end.
stas.kodpi wrote:

при чем тут это.
я совсем не об этом.  я хочу сказать, что заводится в приложение кучу , простите, г...а, а нужное - которое действительно нужно - очень мало...


p.s. - подлизываться очень к месту...

Так и я за то, чтобы проект был лучше, и в обновления попадали в первую очередь нужные фичи. Но вами был задан риторический вопрос, на который последовал такой же риторический ответ.


Теперь по существу заданного вами вопроса. Добавление пользовательских иконок для кнопок на уровне конструктора во первых не такая уж тривиальная задача, а во вторых её реализация имеет множество вариантов. Поясню, что я имею в виду. Сейчас весь пользовательский  графический контент собирается в файл graphics.dll. Однако в некоторых проектах я предпочитаю хранить весь графический контент в базе данных и подгружать его программно после отображения окна-заставки. А вот большинству пользователей наличие нескольких файлов с картинками в папке проекта вообще не мешает. Таким образом, скрипты дают нужную гибкость в выборе решения, где хранить графические ресурсы и как и когда их загружать в программу.


А вы сами как видите механику добавления пользовательских иконок для кнопок?  Отдельный пункт в меню конструктора, который отображает список загруженных в проект графических ресурсов? Или только список иконок для кнопок?


P.S. Я вот радиочекер жду второй год )))

Есть несколько вопросов...

Petr wrote:

1. Проект лежит на сервере в расшаренной папке и все работают по сети.

То есть все пользователи запускают один и тот же екзешник и используют одинаковые настройки (файл settings.ini) ? Хороший вариант, если у всех пользователей одинаковое разрешение экрана и никто из них не пытается менять под себя ширину колонок в таблицах.

Petr wrote:

2. Для удалённой работы доступ к серверу настроен по VPN.
п.с. мне кажется это самый простой способ

Может, дадите несколько ссылок на проверенные способы настройки VPN-соединения (включая настройку серверной части), к которому можно подключиться удалённо (вне локальной сети)? То, что я видел, не кажется мне простым smile.  Правильно ли я понимаю, что в любом случае понадобится фиксированный IP? Или вы рекомендуете использовать платные сторонние VPN-сервисы? 


Возможно, есть какое-то решение "из коробки" ?

1,164

(1 replies, posted in FAQ)

Пример нужный, но я бы рекомендовал делать всё через функции, чтобы проще было использовать в других проектах, например, функция, которая возвращает имя месяца:

function MonthName(ADate:TDate):string;
begin
  case MonthOf(ADate) of
  1: result := 'январь';
  2: result := 'февраль';
  3: result := 'март';
  4: result := 'апрель';
  5: result := 'май';
  6: result := 'июнь';
  7: result := 'июль';
  8: result := 'август';
  9: result := 'сентябрь';
  10: result := 'октябрь';
  11: result := 'ноябрь';
  12: result := 'декабрь';
  end;
end;

Пример вызова функции:

Form1.Label8.Caption := MonthName(Date());
stas.kodpi wrote:

и столько времени прошло с момента создани программы,  а свои иконки на кнопки да и свои кнопки так и не делали..
зачем реализовывать иконки кнопок через скрипты? это 2 век до н.э...
Сделайте выбор своих иконок и своих кнопок....
в чем проблема то?

Действительно, Стас, в чем проблема? Ты бы рассказал нам всем подробней о своих аналогичных проектах в Delphi и как там всё просто у тебя сделано.

1,166

(3 replies, posted in Russian)

Сочувствую вашему горю... Однако, если вы хотите помощи, то нужно приложить ваш проект и указать, о каком поле идёт речь.

1,167

(34 replies, posted in Russian)

Petr wrote:

Добрый день! Напомните плиз: если покупал прогу год назад то бесплатные обновления уже закончились?

Смотря какую лицензию вы покупали. Минорные обновления или пожизненная лицензия?

Еще один вариант, это свои процедуры импорта/экспорта. После обновления программы (включая файл sqlite,db) программа импорта должна корректно загрузить в новую структуру экспортированные данные из старой версии. В зависимости от вида изменений структуры БД  это может быть тривиальной задачей, но бывают случаи, когда скрипт импорта получается довольно мудреным.

sibprogsistem wrote:

нужен компонент для работы с гугл API
иногда нужно взаимодействие с приложениями гугл

о, да!  если бы появилась возможность взаимодействия с гугл-таблицами, то это позволило бы использовать халявный хостинг от Гугла для хранения данных в многопользовательских приложениях, не требовательных к производительности  ))))

1,170

(6 replies, posted in Russian)

Проверил ваш код, все печатает. Ищите причину в принтере/настройках системы.

P.S. Спасибо за рабочий пример печати ))))

uzecherk wrote:

Поясните пожалуйста начинающему, необходимо организовать связь между записями в одной таблице по типу: есть Иванов Иван и его жена Иванова Анна

Создайте для связи целочисленное поле, например:

id_spouse 

...в которое записывайте нужное значение id  для связи.

например, в таблице это будет выглядеть так:


id = 1; Name = Иванов Иван; id_spouse = 2
id = 2; Name = Иванова Анна; id_spouse = 1
id = 3; Name = Сидоров Степан; id_spouse = null

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


P.S. Это подход хорош только для случая, когда пара соединилась навеки и умерла в один день. В реальной жизни чего только не бывает: 5 раз женился 4 раза развёлся, а то и вовсе правоверный многоженец ))) Тогда лучше иметь отдельную таблицу, в которой фиксировать факты создания/расторжения брака. А эта таблица будет иметь две ссылки на таблицу с фамилиями, для мужа и жены.

DriveSoft wrote:

Если кому то еще данный функционал был бы полезен, дайте знать.

В настоящий момент я для упорядочивания скриптов в больших проектах использую имеющийся механизм USES (https://vk.com/@createmyvisualdatabasea … m-poryadok) , однако у него есть существенный недостаток: редактирование .PAS файлов, отличных от SCRIPT.PAS, приходится делать в сторонней программе, а при компиляции при обнаружение ошибки не указывается, в каком именно модуле она обнаружена. Если добавить возможность редактирования всех программных модулей и правильное отображение места ошибки, то это могло бы быть хорошим решением, которое успешно применяется в IDE Delphi.  А вот добавление автоматического создания .PAS файлов с именем формы считаю нецелесообразным - для простых проектов это ненужное усложнение. Ведь одно из главных преимуществ MVD - возможность создания простых проектов без написания кода.


Что же касается хэштегов, то это скорее из области механизмов автоматического документирования.


А вот группировка таблиц - идея неплохая.  Например, двухуровневое дерево: первый уровень - группа, второй - таблицы группы. По умолчанию все таблицы в одной группе, но чтобы была возможность создавать свои группы.  И хорошо бы комментарии добавлять к группам, таблицам и полям smile


Да, такая-же группировка и для форм пригодится: когда их несколько десятков, прокрутка списка начинает утомлять smile

1,173

(28 replies, posted in Russian)

Предлагаемые изменения в вашем проекте:

1,174

(28 replies, posted in Russian)

Попробуйте так:

http://myvisualdatabase.com/forum/misc.php?action=pun_attachment&amp;item=5931&amp;download=0

Это для поиска по полям "Контакт", "email", "Городской", "Сотовый".  Если нужно сюда же добавить поля из связанных таблиц, то придется учить SQL и добавить нужные поля через запрос SELECT  smile


Я не собирался давать вам наставления или нравоучения, это привилегия для моих учеников. Вам - только советы:


1. Не используйте в названии полей кириллицу - это усложнит вам составление SQL-запросов.
2. Прочитайте книгу автора этой системы, там есть много из того, что вы ищите: http://myvisualdatabase.com/forum/viewtopic.php?id=2554

1,175

(187 replies, posted in General)

tcoton wrote:

How about opening MyVisualDatabase to plugins developed by the community? With a very strong validation process to make sure that data and privacy cannot be compromised, I think that would bring some awesome features.


If initially the project architecture was not designed for plug-ins, it is unlikely to be easy to screw this feature into a mature project. Specify what kind of plug-ins you want to see in this project? Visual components? Components for working with data (other DBMS)?


Usually a plugin replaces some standard module and differs from the rest only in appearance. Or the plugin uses API to expand the functionality of the system.


If I'm not mistaken, in the current implementation of script support, to add each new class, you need to rewrite the core of the program. I don’t even have an idea yet how this could be implemented, but the last word is up to the developer of this system.


In the meantime, you can use the standard DLL mechanism to expand functionality.