У пользователей иногда не установлен на ПК ни MS Office, ни Calc.
Как определить, какая программа привязана к расширению xls, и экспортировать данные в нее.
Например, часто встречается WPS Office
Как взаимодействовать с ним?.

Необходимо подключиться к серверу MySql к базе, которая не создавалась в MVD и получить размеры всех таблиц в базе.
Для этого использую такой cкрипт:
      Application.ProcessMessages;
      {$MySQL disable_connectdialog}
      Form1.MySQLConnection.Server := 'server.ru';
      Form1.MySQLConnection.Port := 3306;
      Form1.MySQLConnection.Username := 'name';
      Form1.MySQLConnection.Password := 'passsss';
      Form1.MySQLConnection.Database := 'dbname';

      try
         Form1.MySQLConnection.Connect;
      except
         ShowMessage('Соединиться с сервером базы данных '+Form1.MySQLConnection.Server+ ' на порт '+ IntToStr(Form1.MySQLConnection.Port) + ' не удалось.');
         exit;
      end;

      if Form1.MySQLConnection.Connected then
      begin
         showmessage('соединение с сервером успешно');
         sql_request := 'SELECT table_name AS `Table`, round(((data_length + index_length) / 1024 / 1024), 2) `Size in MB` FROM information_schema.TABLES  Order by `Size in MB` DESC';
         showmessage (  SQLExecute(sql_request) );

     end;

Однако, этот MySql запрос возвращает ошибку: no such table: information_schema.TABLES
Соединение устанавливается успешно.
Запрос SELECT отлажен в другом приложении.
Но в данном случае почему то не срабатывает?
В чем может быть причина?

Запускаю программу на ноуте, работающей с MySQL.
На нем же установлен и MySQL сервер.
Закрываю ноут без выключения ОС и без выхода из своей программы.
Открываю ноут - все программы "просыпаются".
Но, при попытке открыть какое либо новое окно своей программы, возникает ошибка "lost connection".
Приходится выходить из программы и заново ее запускать.
Каким образом сделать так, чтобы соединение само восстанавливалось, если потерялось при засыпании?

По непонятной причине первой стала открываться не главная форма (Form1).
Главная форма как положено расположена первой по порядку на вкладке форм и имеет оранжевый цвет.
Однако, перед ее открытием открывается другая форма (Form2), которая должна открываться с главной формы при клике на таблице, но никак не первой.
Причем, если на событие OnShow Form2 повесить проверку CalledForm, то отображается как "Sender: 0"
Т.е. ее никто не вызывает, а она сама решила показываться.
В чем может быть причина?

У полей Edit и Memo есть свойство Text, значение которого можно задать при разработке формы.
А есть ли способ сохранять значение этих полей без базы данных или внешнего файла?
Т.е. эти поля у меня очень редко изменяются пользователем, но когда он их изменит, то при следующем запуске программы значение полей должно быть такое, какое было изменено пользователем.

Когда работаю на работе, то в БД пишется ссылка на файл: d:\Рабочие документы\Клиенты\Клиент99\Договор1.doc
Когда надо работать дома, то копирую все файлы на ноут, но в другую папку.
Получается к файлу путь такой: H:\Мои документы\Архив\Клиенты\Клиент99\Договор1.doc
Таким образом, постоянным является только часть пути \Клиенты\Клиент99\Договор1.doc
Надо иметь возможность открывать файл в зависимости от того, какой корень указан в настройках при запуске программы.
Т.е. либо из d:\Рабочие документы, либо из  H:\Мои документы\Архив

Можно ли как-то в компоненте DBFile сохранять в БД не абсолютный путь к файлу (link file), а относительный?
А при открытии подставлять нужный корень?

Три последовательные формы приложения свернуты в панель задач (wsMinimized) из третьей формы.
Когда кликаю на панель задач, то отображается первая форма, а две другие нет (они свернуты).
Но фокуса на первой форме нет. Приходится кликать на ту форму, из которой программно сворачивал формы.
Можно ли как-то получить событие клика по приложению в панели задач(то, что оно стало активным), чтобы программно все три формы развернуть?

Спасибо огромное, vovka3003!
Ваш скрипт рабочий!
Стоит задача закинуть базу MySQL на хостинг, чтобы к ней сотрудники имели доступ и из дома.
У хостинга есть панель управления CPanel.
В ней надо указывать IP адреса удаленных подключений к БД.
Но, народ подключается с динамических IP, поэтому приходилось сначала определять IP клиента, потом через браузер логиниться в CPanel, ручками указывать IP удаленного клиента и только потом работать с приложением.
Теперь все проще!
Создал API токен в CPanel (позволяет выполнять функции в Cpanel без пароля).
Скриптом авторизуемся в Cpanel:
whr.SetRequestHeader('Authorization',Format('cpanel %s:%s',[user,token]))
и выполняем добавление удаленного хоста:

url = 'https://mysite.ru:2083/execute/Mysql/add_host?host=124.124.124.124'

35

(6 replies, posted in Talks about all)

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

Каким образом реализовать в MVD следующий php код?

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,0);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER,0);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER,1);

    $header[0] = "Authorization: whm $user:$token";
    curl_setopt($curl,CURLOPT_HTTPHEADER,$header);
    curl_setopt($curl, CURLOPT_URL, $query);

    $result = curl_exec($curl);

    $http_status = curl_getinfo($curl, CURLINFO_HTTP_CODE);

Поиск по зашифрованным полям базы данных можно в ряде случаев решить за счет организации поиска не в самой базе, а визуальной фильтрацией строк в TableGrid, в которую были загружены расшифрованные данные.
См. пост http://myvisualdatabase.com/forum/viewtopic.php?id=6310

Спасибо!

Есть таблица, сформированная как обычно запросом по БД.
Надо реализовать поиск по одному из столбцов так, чтобы неудовлетворяющие условию строки скрывались.
Но, надо это сделать без использования dbFilter.
Т.е. поиск должен работать по первоначально загруженной запросом таблице без обращения с фильтрующим запросом к БД.

Задача решена:
в одном из постов английской версии форума 2017 года нашел скрипт кодирования данных посимвольным методом.
Немного изменил его для получения шифрования/дешифрования алгоритмом RC5.
Теперь в полях формы и таблицах данные отображаются в нормальном виде, а в базе данных - в зашифрованном.
Т.е. подключение к базе данных вне разработанного мной приложения не позволяет понять, что в ней хранится.
Ключевое слово планируется менять периодически.
При смене ключа, конечно, надо запускать скрипт раскодировки данных старым ключом и кодировки новым.
Но, это уже совсем просто.
...
Но, есть два "но".
Скрипт работает с полями базы данных  только текстового типа.
Шифрование по определению производится в символы шестнадцатеричной системы исчисления.
И если в БД тип поля указан как "Целое число" или "Деньги", то запись в БД приводит к ошибке.

Второе - не работает поиск по зашифрованным полям.

Есть необходимость шифровать на уровне приложения некоторые данные, записываемые в БД MySQL.
Это названия контрагентов, их контактные данные, отпускные цены, файл коммерческого предложения.
Цель - защитить базу данных от попадания третьим лицам, чтобы они не смогли прочитать данные, не имея моего приложения.
Шифрование на уровне MySQL не подходит.
Вопрос - есть ли какой-нибудь способ реализовать это?
Как привязать шифровку/дешифровку к некоторым элементам форм и некоторым столбцам таблиц?

Есть ли возможность использовать какую-либо функцию для склонения ФИО и должностей? Надо переводить из именительного падежа в дательный для печати адресных наклеек.
Т.е. Генеральный директор Иванов Петр Сергеевич должен быть переведен в Генеральному директору Иванову Петру Сергеевичу.

Обращаю внимание разработчика, что если в новой бета версии оставить код самостоятельного перевода контекстного меню, например, такой: Frm_1.TableGrid_1.dbPopupMenu.Items.Find('Find').Caption := 'Найти'; то при открытии формы с таблицей выпадает ошибка:
Access violation at address 00E3A564 in module 'kp_maker.exe'. Read of address 00000000.

В контекстном меню таблиц пункты имеют английские надписи:
Find, Copy cell, Copy row, Copy all, Show record.
Для перевода на русский язык этих надписей можно использовать такой скрипт:
       Frm_1.TableGrid_1.dbPopupMenu.Items.Find('Find').Caption := 'Найти';
       Frm_1.TableGrid_1.dbPopupMenu.Items.Find('Copy cell').Caption := 'Копировать значение в ячейке';
       Frm_1.TableGrid_1.dbPopupMenu.Items.Find('Copy row').Caption := 'Копировать строку';
       Frm_1.TableGrid_1.dbPopupMenu.Items.Find('Copy all').Caption := 'Копировать все строки';
       Frm_1.TableGrid_1.dbPopupMenu.Items.Find('Show record').Caption := 'Показать запись';
Но, этот скрипт работает только по конкретной таблице конкретной формы.
Каким образом можно сделать перевод контекстного меню сразу по всем таблицам всех форм?

Этот запрос сортировки не содержит.
Соответственно, при открытии формы все записи выводятся в порядке их id.
При этом, дата проекта выглядит как dd.mm.yyyy.
Но, дата нигде не форматируется к такому виду!
Если кликнуть на заголовок столбца с датами, то сортировка по датам срабатывает неправильно.
Такое ощущение, что таблица не понимает, что в данном столбце даты, а полагает, что это обычный текст.
...
Напоминаю, что данные в таблицу поступают не через настройку свойства Settings у таблицы,
а заносятся нажатием на кнопку, у которой на свойство Action подключен этот SQL запрос.
Может быть поэтому заполненная таблица не знает типа данных в cтолбцах?

Сортировки и форматирования в запросе никаких не делаю.
Дату беру так: Tbl_Projects.Project_Date as 'Tbl_Projects.Project_Date'
форматирование даты сейчас закомментировано.   
Полный текст запроса приведен ниже.
Он большой, т.к. рассчитан еще на фильтрацию по значениям ряда полей на форме

.
.
.


    -- Запрос по кнопке Btn_Do_Project_Search 
   
    SELECT DISTINCT 
   
    CAST(Tbl_Projects.id AS Unsigned),     
                                                                                 
    -- DATE_FORMAT(Tbl_Projects.Project_Date,'%Y-%m-%d') as 'Tbl_Projects.Project_Date' /* Дата проекта из строки преобразована в дату
   
    Tbl_Projects.Project_Date as 'Tbl_Projects.Project_Date' ,                                                     
   
    Tbl_Projects.Project_Num as 'Tbl_Projects.Project_Num' /*Номер КП*/  ,
   
    Tbl_Projects.Project_Sum as 'Tbl_Projects.Project_Sum' /*Сумма КП*/  ,
                                                           
    Tbl_Clients.Client_Nick as 'Tbl_Clients.Client_Nick'  /*Имя заказчика*/  ,   
   
    Tbl_Projects.RFQ_From as 'Tbl_Projects.RFQ_From' /*Запрос от */  ,
   
    Tbl_Projects.RFQ_email as 'Tbl_Projects.RFQ_email' /*email - запроса*/  ,
                                                               
    Tbl_Projects.Project_Nick as 'Tbl_Projects.Project_Nick' /*Имя проекта (Шифр)*/  , 

    Tbl_Projects.Last_Project_Message as 'Tbl_Projects.Last_Project_Message' /*Комментарий к проекту*/  ,
                                                                                             
    Tbl_Project_Statuses.Project_Status_Name as 'Tbl_Project_Statuses.Project_Status_Name' /*Статус проекта, например, Готовим КП*/  , 
                                                                                                 
    CASE WHEN Tbl_Projects.IsClosed = 0 THEN 'ОТКРЫТ' ELSE '-' END as 'Tbl_Projects.IsClosed'    /*Состояние проекта - Открыт/Закрыт*/  ,
                                                                   
    Tbl_Projects.id_Tbl_Clients as 'Tbl_Projects.id_Tbl_Clients'   /*ID заказчика в таблице Проектов*/  ,   
                                                                                       
    Tbl_Projects.id_Tbl_Project_Statuses as 'Tbl_Projects.id_Tbl_Project_Statuses'  /*ID статуса в таблице проектов. Не удалять, т.к. отбор по статусу не будет работать*/ , 
   
    Tbl_Colors.Color_HEX_Code as 'Tbl_Colors.Color_HEX_Code' /* Цветовая метка */,     
   
    Tbl_Colors.Color_Name as 'Tbl_Colors.Color_Name' /* Значение метки */,
                               
    Tbl_Projects.id    /* id должен быть в конце, чтобы работало штатное редактирование/удаление записи*/

    FROM  Tbl_Projects                                                                 
   
    LEFT OUTER JOIN Tbl_Clients ON Tbl_Projects.id_Tbl_Clients=Tbl_Clients.id
    LEFT OUTER JOIN Tbl_Project_Statuses ON Tbl_Projects.id_Tbl_Project_Statuses=Tbl_Project_Statuses.id 
    LEFT OUTER JOIN Tbl_Colors ON Tbl_Projects.id_Tbl_Colors=Tbl_Colors.id 
   
    WHERE                                       
(CASE WHEN ({DateTimePicker_Period_From} IS NULL) THEN 1=1 ELSE ( Date(Tbl_Projects.Project_Date) >= Date({DateTimePicker_Period_From})) END) AND   
(CASE WHEN ({DateTimePicker_Period_To} IS NULL) THEN 1=1 ELSE ( Date(Tbl_Projects.Project_Date) <= Date({DateTimePicker_Period_To})) END) AND
   
    (CASE WHEN ('{Edit_Search_Project_ID}' = '') THEN 1=1 ELSE ( Tbl_Projects.id = '{Edit_Search_Project_ID}') END) AND
   
    (CASE WHEN ('{Edit_Search_Project_Number}' = '') THEN 1=1 ELSE ( Tbl_Projects.Project_Num LIKE '%{Edit_Search_Project_Number}%') END)  AND
   
    (CASE WHEN ('{Edit_Search_Project_Client}' = '') THEN 1=1 ELSE ( (Tbl_Clients.Client_Nick LIKE '%{Edit_Search_Project_Client}%') OR
                                                                        (Tbl_Projects.RFQ_From LIKE '%{Edit_Search_Project_Client}%') OR
                                                                        (Tbl_Projects.RFQ_email LIKE '%{Edit_Search_Project_Client}%') ) END)  AND
   
    (CASE WHEN ('{Edit_Search_Project_Nik}' = '') THEN 1=1 ELSE ( (Tbl_Projects.Project_Nick LIKE '%{Edit_Search_Project_Nik}%') OR
                                                                  (Tbl_Projects.Last_Project_Message LIKE '%{Edit_Search_Project_Nik}%') OR
                                                                        (Tbl_Projects.RFQ_body LIKE '%{Edit_Search_Project_Client}%')) END)  AND

--    (CASE WHEN ({ComboBox_Project_Status} < 0) THEN 1=1 ELSE ( Tbl_Projects.id_Tbl_Project_Statuses = '{Edit_StatusForSQL}' ) END) AND   

    (CASE WHEN ({ComboBox_Project_Status} < 0) THEN 1=1 ELSE ( Tbl_Projects.id_Tbl_Project_Statuses = '{ComboBox_Project_Status}' ) END) AND 

    (CASE WHEN ({CheckBox_IsClosed} = 0) THEN (Tbl_Projects.IsClosed = 0) ELSE ( (Tbl_Projects.IsClosed = 1) OR (Tbl_Projects.IsClosed = 0) ) END)

Форматирование даты из запроса убрал.
Оказалось, что оно там и не нужно было.
Несмотря на то, что в самой базе дата хранится как yyyy-mm-dd, она выводится в таблицу как dd.mm.yyyy даже без скрипта.
Проверил - это определяется региональными настройками Windows.
Если поменять формат даты в настройках Windows, то таблица так и будет отображать.
Но, сортировка то происходит так, как будто в столбце не даты, а текст!
Т.е. сортировка дат происходит неверно.
....
Попробовал в запросе форматировать дату как yyyy-mm-dd.
Она успешно выводится в таблицу именно таким форматом.
А потом повесил на OnChange и AfterSort скрипт TNxDateColumn(Form1.TableGrid_1.Columns[1]).FormatMask := 'dd.mm.yyyy';
Но, он почему-то не срабатывает и дата остается в формате как было в запросе, т.е. yyyy-mm-dd
....
Есть ли у кого-нибудь мысли, как заставить столбец сортироваться как yyyy-mm-dd, а отображаться как dd.mm.yyyy ?

Таблица заполняется данными с помощью кнопки SQL запросa.
Столбец с датой в запросе выглядит так:
DATE_FORMAT(Tbl_Projects.Project_Date,'%d.%m.%Y') as 'Tbl_Projects.Project_Date' /* Дата проекта из строки преобразована в дату */ ,
Сортировка в таблице по умолчанию задана по id проекта, а не по дате.
Если нужно отсортировать список проектов по дате, то пользователь кликает на заголовок столбца с датой.
Но, сортировка происходит как у текстовых данных, а не как у дат.
Т.е. сначала идут все первые числа всех месяцев, потом вторые числа всех месяцев, затем третьи всех месяцев и т.д.
Как сделать корректную сортировку столбца с датами при клике на заголовок столбца?
....
Сообщение модератору форума: поиск по форуму очень неудобен, т.к. между запросами надо выдерживать 30 секунд.
Получается, что проще задать свой вопрос в форуме, чем попытаться найти ответ среди ранее заданных вопросов.

Вопрос решен:
В дизайнере отчетов повесил на событие бенда отключение его видимости, если кол-во товара меньше указанного.
Т.е., например, если кол-во товара меньше 1, то строки с нулевым кол-вом в отчете не выводятся.
procedure MasterData1OnBeforePrint(Sender: TfrxComponent);
begin
   if <Report."Table1.Quantity"> < <Edit_1> then MasterData1.Visible := False ELSE MasterData1.Visible := True; 
end;

На поле Edit повесил процедуру OnChange :
Form1.Table1.dbFilter := 'Quantity >= ' + VarToStr(Form1.Edit1.Value);
Form1.Table1.dbUpdate;
Работает как надо - в таблице скрываются значения, меньшие введенной цифры.
Но, у меня еще есть  стандартно настроенная кнопка "отчет"
В настройках кнопки добавил поле Edit1 в раздел компонентов, участвующих в поиске.
Но, отчет выводит строки без учета фильтра по количеству (т.е. без учета значений в Edit1).
Что-то не пойму, как добавить в отчет фильтр по Edit1?