Последняя версия DataExpress 3 beta от 18 июля 2020 года.
Изображение Скачать | Изображение Что нового?
См. также: Энциклопедия DX | Форум на develop-soft | Расширения
ИзображениеИзображениеИзображение

Каталог расширений

# Название Описание Автор
1 "DX Хранилище файлов" - модуль работы с файлами "DX Хранилище файлов" - это комплекс, состоящий из взаимодействующих и программно связанных друг с другом форм и модуля расширений, в совокупности предназначенный для организации системы загрузки/выгрузки, хранения и манипуляций с одним или группой файлов.

МОДУЛЬ
jurist23rus
2 ALLOW_SYMVOLS. (Проверка текста на допустимые символы) Функция проверяет текст на содержание в нем допустимых символов.
Разрешенные символы.epas.zip

Примечание: после установки расширения функция появится в группе "Текст".
Гocть
3 DX Loger - модуль логирования действий пользователя DX Loger - это комплекс, состоящий из взаимодействующих и программно связанных друг с другом форм и модуля расширений, в совокупности предназначенный для организации системы логирования (журнализирования) определённых действий пользователя и фиксации изменений в журнале событий.

Автор: jurist23rus
Последняя версия: 3.2 от 31 марта 2019 г.

РЕПОЗИТОРИЙ
jurist23rus
4 DX PLUS Множество полезных вещей. Расширение включает в себя следующие действия:
1. Показать окно списка.
2. Создать закладку с формой.
3. Обновить запрос.
4. Очистить таблицу.
5. Добавить разделитель на панель инструментов.
6. Кнопка на панели инструментов.

Текущая форма.
7. Вставить значения в поля текущей формы.
8. Начать добавление записи в текущую форму.
9. Начать редактирование записи в текущей форме.
10. Отменить изменения в текущей форме.
11. Перейти на запись текущей формы.
12. Сохранить запись текущей формы.
13. Удалить запись текущей формы.
Форма.
14. Добавить запись в форму.
15. Показать запись формы.
16. Редактировать запись формы.
17. Удалить записи формы.

Список будет пополняться.

DX_PLUS 1.1.zip

DX_PLUS.epas
admin
5 HTTP_GET - Функция для выполнения простого web-запроса Функция: "HTTP_GET". Функция для выполнения HTTP-запроса методом GET (все параметры в URL).
Группа: "Интернет"

Может пригодится во многих случаях, где веб-сервисы отвечают на запрос простым текстом (plain). Коллекция таких сервисов с примерами использования будет пополняться ниже.

Примеры:

Code: Выделить всё

setfield('Результат',
HTTP_GET(
text('https://bitly.su/api/?
api=baa733ebb140b5e38f825e0407e64f4b7572f203
&url=[URL]
&format=text'))
)   

Результат: https://bitly.su/xhzd

Примечание: API ключ регистрируем свой. Это бесплатно.

Code: Выделить всё

setfield('Результат',
   HTTP_GET('https://base.mydataxpress.ru/myip/')
)   

Результат: Ваш внешний IP адрес интернет

Code: Выделить всё

setfield('Результат',
   HTTP_GET('https://mydataexpress.ru/latest_version.php')
)   

Результат: ДД.ММ.ГГГГ

...

Примечание:
Запрос выполняется в синхронном режиме и при задержках в ответах от запрашиваемых сервисов или с медленным интернетом могут происходит подвисания интерфейса программы.



[ Скачать ]

dxdb_icon Демо


Develop-Soft
6 IDDT Идентификатор по времени и дате. Простенький код для получения уникального ключа из даты и времени.

Code: Выделить всё

{@function
OrigName=IDDT
Name=IDDT
Args=dt
Result=n
Group=Идентификаторы
Description=Функция преобразует дату и время в ключ для сравнения.
<br>
<br>IDDT ([Поле Даты],[Поле Времени]) результат число
<br>Из 09.08.2018 21:28:22 получим 20180809212822
@}

function IDDT (DT,TM:variant):int64;
var
mn,yr,dy,df,tf:string;
begin
if (DT = null) or (TM = null ) then exit;
df:=StringReplace(datetostr(DT),'.','',[rfReplaceAll]);
tf:=StringReplace(timetostr(TM),':','',[rfReplaceAll]);
delete(df,3,6);
dy:=df;
df:=StringReplace(datetostr(DT),'.','',[rfReplaceAll]);
delete(df,1,4);
yr:=df;
df:=StringReplace(datetostr(DT),'.','',[rfReplaceAll]);
delete(df,1,2);
delete(df,3,4);
mn:=df;
result:=strtoint64(yr+mn+dy+tf);
end;


Теперь уже знаю про таймштамп.
SirWolf
7 j-функции j-функции
Автор: Jurist23rus

DX Loger - служит для организации системы логирования (журнализирования) определённых действий пользователя в журнале событий вашей базы данных.
DX Хранилище файлов - модуль работы с файлами в базе данных.
Форматирование даты и времени - модуль содержит функции для представления даты и времени в нужном формате.

Модуль:j-modul
Версия: 7.1 от 27 октября 2017 г.
Описание: содержит функции.
Объединяет в одну строку значения столбца таблицы. Аналог штатной функции Merge, но в отличие от последней
позволяет фильтровать результат.

Code: Выделить всё

MergeIf ('ИмяДочернейФормы', 'ИмяПоля', ';', '[ИмяПоля]<>null')

Обновляет запрос расположенный на форме.

Code: Выделить всё

QueryUpdate ('ИмяЗапроса')

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

Code: Выделить всё

ABC ([Любое поле])

Можно забыть об этом:
nz (ABС ([Числовое поле]), 0)
ABC (cnum ([Текстовое поле]))
Функция сама сделает преобразования.

j_module v7.1.zip


Модуль: AutoCloseForm
Версия: 3.1 от 14 июля 2017 г.
Описание: содержит функцию AutoCloseForm.
Автоматически закрывает форму через установленный промежуток времени.

Code: Выделить всё

AutoCloseForm (120, 30, 'OffTimer')

AutoCloseForm v3.1.zip

AutoCloseForm v3.2.zip

Версия 3.2:
- в данной версии функция не сохраняет сделанных на форме изменений данных, а отменяет их, так как сохранение данных, в некоторых случаях приводило к ошибке.
Для тех кому важно сохранение данных, при закрытии функцией формы и на форме нет пустых обязательных полей как в этом примере может продолжать пользоваться версией 3.1

Версия 3.1:
- попытка закрыть предупреждающее окно комбинацией клавиш Alt+F4 не прервёт работу функции и будет равносильно нажатию второй кнопки в окне, то есть произойдёт отключение таймера либо его перезапуск, в зависимости от заданных параметров.
- оптимизирован и модернизирован код (внешне это никак не видно, но в будущем исключит возможные ошибки совместимости с другими функциями или скриптами).

Версия 3:
-полная поддержка запросов, в том числе с таблицей на нем;
- поддерживает работу до 5 запросов на форме (больше делать не стал, не вижу смысла);
-при использовании в дочерней форме выводит сообщение в штатное окно ошибок функции (красный пятачок на форме) не нарушая работу программы (защита от тех кто не читает справку);
- ввёл третий параметр, позволяющий менять назначение кнопки на окне сообщения: кнопка может выключать таймер или откладывать его (на усмотрение разработчика базы).


Модуль: ExportToExcel
Версия: 1.1 от 19 ноября 2017 г.
Описание: содержит функцию ExportToExcel + действие для кнопки.
Экспортирует данные формы в Excel

Code: Выделить всё

ExpotToExcel ('', 'Поле1;Поле2;Поле3', '')

ExportToExcel v1.2.zip


v.1.0 - для DX версий до 12 ноября 2017 г., то есть версий без "активных кнопок"
v.1.1 - содержит графическую оболочку в виде действия в кнопке (см. скриншот), её можно устанавливать только на DX от 12 ноября 2017 г. и более поздние выпуски.

2017-11-19_22-09-09.png

Обсуждаем модули ТУТ
jurist23rus
8 kok80-ExportToExcel (LibreOffice calc) kok80-ExportToExcel ver 3.0
возможности (выбираются в действиях при запуске):
- экспорт в LibreOffice calc вместо Excel
- кнопку на панель главной формы(экспорт активной формы)
- кнопку на панель всех запросов
- в контекстное меню всех форм
- в контекстное меню всех форм: выделенные строки
- в контекстное меню всех запросов
- в контекстное меню всех запросов: выделенные строки
- в контекстное меню всех сводных таблиц
- мультивыбор во всех формах
- мультивыбор во всех запросах

в действиях формы:
- Форма - сделать мультивыбор
- Запросы формы - сделать мультивыбор (выбрать нужные запросы)

Если подключить модуль как внешний {$I kok80-ExportToExcel}, то можно использовать

Code: Выделить всё

procedure GridToExcel(sender:TObject)

в качестве sender понимает TdxForm, TdxQueryGrid, TdxSQLQuery, TdxPivotGrid.

Экспорт осуществляется через буфер обмена, если в буфере был текст-он восстанавливается после экспорта.


dxdb_icon Демо


kok80-ExportToExcel 3.0 Изображение Скачать
kok80
9 kok80-ObjectAndQueryOnDBLClick Устанавливает OnDBLClick на все объекты, поля объектов, запросы на всех формах: при двойном клике открывается исходная форма в режиме редактирования, если позволяют права доступа, вне зависимости от состояния (чтение/редактирование) исходной формы. В DataExpress, если исходная форма в режиме только для чтения, все формы из нее тоже открываются в режиме только для чтения (для объекта нет в контекстном меню "изменить").
Для запросов предыдущий обработчик OnDBLClick вызывается только в случае ошибки или нескольких источников-форм в запросе (иначе бы 2 раза подряд открывалась исходная форма).

Как всегда, писал для себя, но пожелания и баг репорты приветствуются.
kok80
10 Kroks-функции KROKS-функции
Автор: Kroks
Описание: добавляет новую функцию.
K_ZAGOLOVOK_OKNA - выводит в заголовок окна редактирования записи заданный текст.
K_KIR_LAT - транслитерация кириллицы в латиницу.
jurist23rus
11 NSORT. Функция "естественной" (как в Windows) сортировки значений списка. Может использоваться для сортировки списка файлов и каталогов, IP-адресов, результатов, полученных из встроенных и других функций, прочих произвольных списков.

Изображение Изображение
Параметры:

1. [текст] Текст с разделитем CR+LF (#13#10, newline - комбинация возврата каретки и символа новой строки.).

Результат:

Отсортированный текст с исходным разделителем.

Пример:

Code: Выделить всё

NSORT(
'Текст 1
Текст 10
Текст 2
Текст 20
Текст 3
...')

Результат:

Code: Выделить всё

Текст 1
Текст 2
Текст 3
Текст 10
Текст 20
...


Примечание:

Использует медленный алгоритм и НЕ рекомендуется для сортировки больших (>1000 строк) текстов.

dxdb_icon демо • [ Скачать ]
Develop-Soft
12 RecordEditor - функции работы с данными Описание jurist23rus
13 SpinEdit из компонента ЧИСЛО Так как меня тут не заметили, пришлось ваять расширение.
Добавляет к компоненту ЧИСЛО кнопки UP/DOWN, нажатие на которые в режиме редактирования формы увеличивает/уменьшает значение выбранного числового поля. Работает только если отключена стандартная кнопка компонента ЧИСЛО в контекстном меню компонента.

08.05.20 v 1.1 Добавил управление колёсиком мыши.

dxdb_icon Демо


drts
14 Ввести на основании Ввести на основании - действие кнопки.
Создает новый документ на основании текущего, заполняет поля и копирует данные подчиненных форм (таблиц).


Изображение



[ Скачать ] dxdb_icon Демо

Похожие расширения: "Заполнить по"


Develop-Soft
15 Веб-печать Действие кнопки: "Веб-печать". Выводит указанный контент в браузере посредством встроенного в программе http-сервера.

Изображение

Опции и параметры:

Контент для вывода - текстовое содержимое для вывода в браузер. По-умолчанию любой тип передаваемого содержимого отправляется браузеру как html (кодировка utf-8). В выражении могут участвовать поля формы, поля и вычисляeмые поля запроса, переменные (getvar), функции, возвращающие текст или преобразованные к типу "текст".

Порт - числовое значение в диапазоне 80-65535 (по-умолчанию 8800). При конфликте выбранного порта с существующим открытым портов в системе - выдается соответствующее сообщение и порт необходимо сменить.

Открыть в программе/браузере - принудительно устанавливает указанное приложение для открытия страницы. По-умолчанию пустое и открывает контент через сопоставленный с интернет-страницами браузер в системе.
Можно указать коротко: chrome, opera, firefox, iexplore

Примечание:

- Способ вывода предпочтителен в случаях, когда нежелательно оставлять следы и мусор в файловой системе (браузеру передается поток напрямую). Позволяет использовать теги и код JavaScript, которые при печати не пропускает стандартный html-шаблон.
- После отдачи контента браузеру сервер останавливается и нажатие кнопки "обновить" в браузере не даст никакого результата. Для повторного открытия необходимо еще раз нажать кнопку с действием.
- Вывод картинок не поддерживается.




[ Скачать ] dxdb_icon Демо


Develop-Soft
16 Видимость или доступность поле + лейба Ранее на форуме выкладывал версию этого модуля, чутка доработал к полноценному формату. Иван
17 Виртуальный запрос на основе TKGrid (исключает Out of Memory) Создает виртуальный запрос поверх запроса. При использовании расширения можно просто выбрать запросы которые нужно создавать. Позволяет обойти Out of Memory при большом количестве записей в БД.

Поддерживает все функциональные свойства обычного запроса (кроме функций, пока что). Выводит нужное количество записей.
Можно добавить на форме список в котором указывать сколько записей выводить иначе выводит количество что входит в видимый запрос.

Есть возможность выбрать открывать на двойной клик источник каждого поля или основной источник запроса 'Не открывать формы объектов'.
Если при записи выражения для выделения цвета ячейки добавить комментарий //font то будет менять цвет не фон, а текст.
Возможность искать по всем полям нужные данные добавив на форме поле для поиска (игнорирует поля даты и времени).
Можно добавит на форме чекбокс для возможности Искать без учета регистра.
Искать по конкретному столбику, для этого в таблице добавлен пустая строка вводя текст в которую и обновляя запрос будет проведена фильтрация.
Поля даты и времени подстраивают дату если она введена с ошибкой (пример: если ввести 12 то выдает 12.06.2020).
Возможность искать выражениями (Пример: >10 & < 100). Поле поиска на форме и поиск по столбику могут работать вместе выводя результат по всем запросам. Для удобства работы добавлено функции getq (аналог get), и sumq аналог sum с ограничением: по вычисляемым полям выводит сумму всех отрисованных строк).

Ограничения:
1. В выходном фильтре нельзя использовать вычисляемые поля.
2. В выходном фильтре в правой части выражений игнорируются выражения с вычисляемыми полями если нужно получать их данные (пример: если будет выражение [Клиент поле запроса]=iif([:Клиент]<>'', [:Клиент], [Клиент поле запроса]) оно будет включено в фильтр если [:Клиент]<>'' и проигнорировано если [:Клиент]=''.
3. Нет возможности сортировки вычисляемых полей.
4. Нет возможности искать по вычисляемым полям через строку поиска запрашивая данные из БД.

2-е расширение идет комплектом QueryTreeTK. Позволяет создавать дерево групп. Если на форме будет найдено совпадение по форме что добавлена как источник дерева и поля в запросе то будет по нему фильтровать записи. Через установку переменных getvar('Источник дерева название формы'|'Название поля') можно получить доступ к полям формы групп и фильтровать выводимые группы дерева при клике на ноду другого дерева (если на форме объект то в переменную запишет текст объекта). Смотрите описание модуля QueryTreeTK.

Версия 1.4:
- исправлено ошибку разбора сложных выражений фильтров внешних и внутренних.
- добавлены функции (включая баланс).

Демо база в виде ссылки. Добавлено 500 тыс. записей несколько вычисляемых полей, деревьев групп, раскраска ячеек.
https://www.dropbox.com/s/90tvt9p9lal93yh/QueryTK_DEMO.FDB?dl=0

Если у вас какая либо ошибка при использовании пишите в комментарии.
Иван
18 Выбор данных из окна списка Подобно стандартной функции "Шопинг" действие открывает форму в окне списка, из которого можно выбирать данные (товары, услуги и т. п.) и вставлять в таблицу текущей формы. Дважды щелкните по записи или нажмите ENTER, чтобы добавить данные в таблицу. Пример использования есть здесь в кнопках "Выбрать товар". admin
19 Выбор объекта из окна отчета Альтернатива выбору объекта из выпадающего списка или окна списка. Выбор объекта осуществляется из окна отчета. Плюсом является более гибкая настройки отбора. admin
20 Выравнивание содержимого полей Действие устанавливает положение содержимого колонок таблицы (подчиненной таблицы) и полей формы (подчиненной формы) cправа, слева, по центру.

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

Например:

Code: Выделить всё

Поле    Выравнивание  В таблице   В форме
----    ------------  ---------   -------
Номер   По центру        ☑          ☐
Номер   Справа           ☐          ☑


Выравнивание содержимого полей.zip
Гocть
21 Вычисляемые надписи в дополнительном статусбаре формы Ну наконец-то доделал свое расширение, учтя, надеюсь, все свои ошибки и желания :)
Данное расширение добавляет вычисляемые надписи в статус бар окна, в котором отображается таблица формы.
Подключать требуется непосредственно к форме справочника или документа.
Позволяет выводить сколько угодно вычисляемых надписей, в дополнительные статусбары,
по отношению к выделенной записи в табличном представлении формы.
Так же, теперь, это расширение, можно подключать к одной форме несколько раз, в итоге будет создано несколько
полей с надписями, например для разделения цен и остатков в разных панелях.
К примеру можно выводить остаток по товару, цену и др. вычисляемые поля.

Но осталось пара вопросов, скорее к автору.
1) Это конечно не критично, но хотелось бы как-то это обойти.
На скринах видно, что при отображении в таблице формы, и если открыть эту-же форму через объект, то меняется сортировка надписей и самих статус баров, не считаю это багом, но буду рад совету как это обойти в расширении.
2) При поиске элемента массива по форме, ранее Вы рекомендовали отключать текущий элемент(переменная Disabled:boolean), если не сложно подскажите когда это надо использовать а когда нет.
Заранее благодарен.
Vofka18
22 Гео-функции МОДУЛЬ НЕ РАБОТАЕТ!

Список функций модуля:

GET_COORDINATES - функция поиска координат на Яндекс-карте по полному или частично введенному адресу.
(требуется интернет-подключение)


FIND_PT_IN_POLYGON - функция для проверки вхождения одной координаты в полигон, состоящий из массива координат. Может применяться для поиска объекта в заданной зоне(зонах).

GET_POLYGON_CENTER - функция поиска приблизительного центра в массиве из множества координат. Может использоваться в качестве указателя при открытии карты в брауере.

VIEW_ON_YMAP - функция открывает в браузере Яндекс-карту и ставит отметку на объект или в точку координат
(автоопределение передаваемого параметра: координаты, адрес, организация).


Более подробное описание имеется внутри функций.

Модуль:
GeoFuncs_v0.1.zip

Демо-база:
GEO_DEMO.zip

Расширения списком
YurAnt
23 Главное меню Состав модуля:

Функция: CLICK_MENU
- Функция ищет пункт меню главного окна по указанному пути и выполняет клик.

Действие: "Кликнуть пункт меню".
Выполняет аналогичное CLICK_MENU действие.

Пример пути для функции/действия: Файл|Подключиться, Сервис|Экспорт данных

Изображение

dxdb_icon Демо онлайн



Клик в главном меню.zip
Develop-Soft
24 групповое изменение / удаление записей формы / запроса Писал для себя, пожелания и бегрепорты приветствуются.

1) делает возможность выбора нескольких записей формы (CTRL + мышка, SHIFT+стрелки)
2) групповое изменение записей формы и запросов ("изменить" - срабатывает при выборе >1 записи)
3) групповое удаление записей формы и запросов

работает только в формах в режиме ТАБЛИЦА
настраивается для каждой формы отдельно (действия формы)

Порядок изменения:
открывает первую выбранную запись формы
все компоненты блокируются, кроме выбранных в настройках (и групповых: группа, закладки)
выбранные в настройках поля подсвечиваются желтым (TdxComboBox не меняет цвет при "только значения из списка")
поля становятся зелеными при изменении значения
при нажатии "Ok" измененные значения применяются к выбранным записям формы

dxdb_icon Демо онлайн

Изображение


kok80-ChangeGroupFields1.4.zip [ Изображение Скачать ]
kok80
25 Дерево для запроса Модуль дает возможность представить данные запроса в виде дерева и использовать его как фильтр для другого запроса. Подробности читайте в справке по действию. Действие называется "Дерево для запроса", группа "Компоненты".

1.3. Исправлена ошибка, возникающая при выборе узла дерева, содержащего кавычки.
1.2. Дерево не учитывало выходной фильтр запроса-источника.
1.1. Исправлена работа с запросами с выборкой из нескольких источников.
1.0. Первая версия.

QueryTree 1.2.zip

QueryTree 1.1.zip

QueryTree 1.0.zip
admin
26 Диаграмма Ганта Диаграмма Ганта отображает данные в виде боксов (полос) на шкале времени. Масштаб может регулироваться от месяцев до часов. Каждый бокс на диаграмме несет в себе следующую информацию: дата и время начала, дата и время окончания, цвет, текст, всплывающую подсказку, название группы. Данные для диаграммы берутся из запроса.

Для работы расширения требуется файл GantChartLib10.dll, который загружается автоматически с сайта mydataexpress.ru и сохраняется в папке программы. Диаграмма отображается в выбранном компоненте "Группа", заполняя всю ее область, включая заголовок.

Обязательные для заполнения параметры отмечены звездочкой. В разделе "Временной интервал диаграммы" вы можете указать поля формы, которые будут задавать минимальное и максимальное время, отображаемое на диаграмме. Обычно эти поля служат фильтром для запроса. Если поля не указаны, то временной интервал будет соответствовать минимальному времени начала и максимальному времени окончания из данных запроса.

Управления диаграммой осуществляется при помощи мыши. Вы можете прокручивать диаграмму, перемещая мышь с зажатой левой кнопкой. Колесиком мыши можно прокручивать диаграмму по вертикали. Масштаб настраивается колесиком мыши с зажатой клавишей Ctrl.

Вы можете указать поле цвета, которым будет окрашиваться соответствующие боксы. Поле должно содержать название цвета (clRed, clGreen, clBlue, clSilver и т. д.) или шестнадцатиричное значение цвета ($0000FF, $00FF00, $FF0000, $CCCCCC, $C0F911 и т. д.). Это может быть поле формы или вычисляемое поле запроса.

Данные на диаграмме отображаются в порядке, определяемым запросом. Боксы могут быть сгруппированы, а могут располагаться по одному в каждой строке (параметр "Группировать боксы").
admin
27 Доступ и безопасность
Состав модуля:

~~~ Функции выражений ~~~

CHECK_PASSWORD - Проверяет пароль текущего пользователя. Можно использовать для временной блокировки без закрытия програмы или "уточнения" доступа к отдельным формам и компонентам (проверка присутствия легитимного пользователя).

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

Вызывает окно смены пароля для текущего пользователя.
Изображение Изображение
Не рекомендуется: Баловаться с паролем единственного разработчика!

~~~

Примечание: функция модуля CheckSpecifiedUserPassword готова к употреблению в других модулях (например для создания авторизации на http-сервере).

Доступ и безопасность_v0.2.2.zip
Develop-Soft
28 Дублирование записи (действие для кнопки) Дублирует запись таблицы. В отличие от штатной кнопки таблицы "Дублировать",при установке соответствующей опции может открыть окно редактирования новой записи. Например, чтобы изменить значения каких-то полей перед сохранением записи.
2018-03-19_21-38-40.png

2018-03-19_21-36-29.png
jurist23rus
29 Заполнить по Расширение для вставки данных из указанной формы в текущую.
Похожие расширения: "Ввести на основании"
admin
30 Иконки главного меню Действие запуска. Устанавливает иконки для главного меню программы.

Изображение

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

Примечание: "опционально" иконки назначены и для пунктов меню дизайнера
Изображение

В планах:
- Добавить пунктам горячие клавиши (где отсутствуют)
- (Возможно) изменить названия некоторых МП на более понятные (например: вместо "Подключиться" = "Менеждер подключений")
- Добавить хинты (подсказки).
(Возможно) перестроить пункты меню. Добавить новые.


[ Скачать ] dxdb_icon Демо

Develop-Soft
31 Импорт данных из CSV и Excel Импорт данных из Excel, CSV и других текстовых файлов, где значения отделены друг от друга точкой с запятой. Вы выбираете файл для импорта, программа считывает данные и показывает их вам в табличном виде. Проверьте данные и, если все в порядке, можете их импортировать. Если в данных найдены ошибки, то они выделяются красным цветом. Данные считаются ошибочными, если тип данных не соответствует типу поля или имеют неправильный формат. Строки с ошибками и пустые строки не импортируются.

Расширение умеет удалять из числовых данных пробелы, понимает многострочные значения, значения в двойных кавычках (двойные кавычки используются, чтобы символы переноса строки и разделитель данных считались частью значения). Также расширение умеет обновлять данные при импорте. Т. е. программа ищет по определенным полям данные и если они есть, то данные обновляются, в ином случае данные добавляются.

Расширение состоит из двух действий для кнопок: импорт в форму и импорт в таблицу.

Для работы расширения требуется версия DataExpress не ниже 31.01.2019.

1.2 - Добавлен импорт из Excel.
1.1 - Внесены правки для совместимости с DataExpress от 31.03.2019.
1.0 - Первая версия.

ImportData 1.1.zip
ImportData 1.0.zip
admin
32 Информация о подключении Действие запуска. Добавляет в главное меню кнопку для отображения информации о подключении и версии сервера.
Изображение
Гocть
33 Кнопка очистки поля Действие формы добавляет в перечисленные поля кнопку очистки. admin
34 Конструктор меню из кнопок Действие формы: "Конструктор меню". Создает меню из кнопок расположенных в указанной "Группе".

Изображение Изображение

Настраиваемые опции:

[Кнопка вызова меню] (обязательная) - любая из кнопок формы, при нажатии на которую будет открываться создаваемое меню.
[Группа кнопок для создания пунктов меню]
(обязательная) - "Группа", внутри которой будут расположены кнопки (пункты меню). При открытии формы в рабочем режиме группа будет программно скрыта а из находящихся в ней кнопок будет создано меню, раскрывающееся по нажатию "Кнопки вызова меню".

В создаваемые пункты меню из кнопок "переезжают": заголовки, иконки, свойства "доступность" и "видимость", событие клика (вычисления/действия/скрипты, завязанные на кнопки выполняются при нажатии на соответствующий пункт меню).

Для создания горизонтального разделителя меню достаточно добавить отдельную кнопку между пунктами и указать текст кнопки "-" (дефис).

Порядок пунктов меню определяет вертикальное расположение кнопок (в расчет берется верхний край кнопки - свойство "top"). Для изменения порядка достаточно в дизайнере передвинуть кнопки выше/ниже относительно друг друга и пункты меню будут выстроены соответственно.

Рецепт видимости/доступности пунктов меню по условию:
1). Скачиваем и устанавливаем расширение "Управление видимостью/доступностью компонентов" отсюда.
2). В него прописываем условие скрытия и ниже в таблице компонентов добавляем требуемые кнопки из группы, участвующие в построении меню. В настройках расширения "Управление видимостью/доступностью компонентов" можно указать любое свойство (Видимость, Доступность) - реакция меню будет соответсвующей.

Примечание:
На одной форме может быть неограниченное подключение действия (по одному на кнопку со связанной группой кнопок)
Вторичное меню (субменю) не поддерживается (и не планируется)




dxdb_icon демо

[ Скачать ]
Develop-Soft
35 Короткие ссылки Функция для укорачивания url с помощью сервиса clck.ru

Code: Выделить всё

https://www.google.com/maps/place/Даниловский+р-н,+Москва,+Россия/@55.7071373,37.6016495,13z/data=!3m1!4b1!4m5!3m4!1s0x46b54b4869e4867d:0x87d973c36502b375!8m2!3d55.7054831!4d37.6377914
= https://clck.ru/D9ttb

Модуль расширений:
Короткие ссылки.zip
Гocть
36 Модуль DaData Изображение
Быстрый ввод адресов, компаний, банков с помощью подсказок онлайн-сервиса DaData.ru

Модуль:
DaData.epas.zip

Тестовая БД:
DaData_example.zip
Внимание! Изменены имена функций!
(после установки этой версии необходимо сменить имена в самой базе)

Модуль:
DaData_1.5.zip

Тестовая БД:
DaData_example_1.5.zip

dxdb_icon Демо в облаке

API-ключ в примере - тестовый. Новый ключ вы можете бесплатно получить после регистрации в сервисе DaData.

Примечание:
1. Сохранена совместимость со старыми названиями функций (достаточно установки модуля поверх старой БД).
с версии 1.5 имена изменены для удобочитаемости... :|
2. Plug&Play: "Автономная" работа через WinAPI (отдельная библиотека libcurl.dll не требуется).
3. На linux-версии DX работать не будет, т.к. используется OLE.
4. На linux под wine по идее заработать должен, т.к. wine очень хитёр... работает.
5.Ввиду специфичности и простоты самодельного xml-парсера возможно некорректное отображение результатов запросов вызываемых с тегированными параметрами (DA_FUNC..('param1.param2...') ) . Полноценное решение выложу немного позже. Пофиксено.

1. Выборка искомого объекта из списка нескольких результатов (в отдельном всплывающем окне или выпадающем списке).
2. Прочёс API DaData на предмет расширения функциональности модуля.
3. При необходимости - расширение функциональности модуля для работы с платными API-функциями DaData.
Расширения списком
YurAnt
37 Модуль drts drts
Автор: drts
Версия: 2.0 от 30.08.2017 г.
Описание: содержит функции
Функция добавляет в контекстное меню пункт для копирования произвольного текста в буфер обмена.
Пример:

Code: Выделить всё

dr_CopyStrToClipboard('Цена изделия:'+ [Цена]+' руб.','Копировать цену изделия',1)

Функция добавляет в контекстное меню пункт для копирования значения указанных полей.
Пример:

Code: Выделить всё

dr_CopyToClipboard('Запрос', '"Поле 1","Поле 2","Поле 3"','Скопировать данные полей в буфер',1)

Функция добавляет в контекстное меню пункт для копирования значения полей выделенной строки.
Пример:

Code: Выделить всё

dr_CopyAllToClipboard('Запрос1', 'Скопировать данные строки в буфер',0)

Функция позволяет включить выделение строки в таблице.
Действие аналогично

Code: Выделить всё

self.grid.options:=self.grid.options+[dgRowSelect];
в скрипте.
Пример:

Code: Выделить всё

dr_GridRowSelect('Запрос1')

scr.png

Функция позволяет включить отображение всплывающей подсказки в ячейке таблицы, если текст не полностью помещается в ней.
scr1.png

Пример:

Code: Выделить всё

dr_GridShowHint('Запрос88')

В этом модуле содержится функция для добавления в окно TListWindow, панели динамического фильтра. При вводе текста в поле поиска фильтр динамически обновляется.
scr3.png

Пример:

Code: Выделить всё

dr_FilterPanel('Объект 1','Поле3')

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

Code: Выделить всё

//[дата_изменения],[Децимал],[Название],[Описание]
nz([Децимал],'')+nz([Название],'')+nz([Описание],'')

поле потом можно скрыть.

В этом модуле содержится функция для добавления панель главного окна поля динамического фильтра. При вводе текста в поле поиска фильтр динамически обновляется.
scr4.png

Пример:

Code: Выделить всё

dr_FilterMainPanel('Поле')

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

Code: Выделить всё

//[дата_изменения],[Децимал],[Название],[Описание]
nz([Децимал],'')+nz([Название],'')+nz([Описание],'')

поле потом можно скрыть.

функция для добавления в заголовок приложения названия БД и имя пользователя
Пример:

Code: Выделить всё

dr_AppName

функция для добавления в заголовок приложения произвольного названия БД.
Пример:

Code: Выделить всё

dr_AppAnyName('текст')

2.0
v1.99 - Исправил ошибку, связанную с передачей фокуса полю поиска.
v1.95 - Добавил кнопку для очистки фильтра в функции dr_FilterPanel, dr_FilterMainPanel
v1.91 - Исправил ошибки, не позволяющие многократное применение функций
v1.83b - Исправил небольшие ошибки.
v1.82 - Добавил функцию добавляющую возможность динамической фильтрации в таблице формы из панели главного окна. Изменил механизм добавления фильтра.
v1.7 - Добавил функцию копирования произвольного текста в буфер обмена.
v1.6 - изменил название глобальных переменных и функций на уникальные (добавил индекс dr_), исправил ошибку из-за которой не срабатывали одновременно функции по параметрам таблицы.
v1.5 - добавил возможность применения функций к запросу, заменил true/false на 1/0, объединил с другими своими модулями
v1.4 - убрал аргумент у функции dr_GridRowSelect за ненадобностью
v1.3 - Добавил функцию включения отображения подсказки ячейки
v1.21 - Исправил досадную ошибку в dr_CopyAllToClipboard (при попытке копирования значения пустого поля возникала ошибка)
v1.2 - добавил функции копирования всей строки dr_CopyAllToClipboard и функцию включения опции таблицы dr_GridRowSelect
v1.1 - появилась возможность указывать несколько полей для копирования

Вопросы можно задавать тут
drts
38 Модуль EX_EXEC EX_EXEC
Автор: Admin
Описание: добавляет новую функцию
EX_EXEC - запускает приложение или открывает файл/ссылку в сопоставленном приложении. Поддерживает указание параметров запускаемого приложения.
ex_exec.zip


Версия с доработками YurAnt для DX от 12.11.2017 г.:

Описание доработки:
Совмещены функции выражений + действие:
24.11.17: Оптимизировано "действие" (ранее при отсутствии параметров открывался проводник Windows, теперь ничего не происходит)
exec_act.epas.zip

Совершить исходящий вызов с компьютера на номер телефона:
Варианты команды:
tel:+79000000000
'tel:'+[Клиент|Телефон]
'tel:'+get('Запрос_Контакты','Телефон')


...в процессе заполнения...


Изображение
YurAnt
39 Модуль neitri NEITRI
Автор: Neitri
Версия: 0.15.1 от 1 декабря 2018 г.
Новое в версии: устранен конфликт IntToHex
Описание: содержит набор новых функций.
ObjectVisible - Функция для управления видимостью объектов. Если условие истинно, указанный объект отображается иначе будет скрыт.
True - Возвращает значение Истина.

Code: Выделить всё

IIF(TRUE,'Сумма','Итог')
Результат: Всегда будет возвращать 'Сумма'.
False - Возвращает значение Ложь.

Code: Выделить всё

IIF(FALSE,'Сумма','Итог')
Результат: Всегда будет возвращать 'Итог'.
TabOff - Функция для отключения перехода на объект по нажатию кнопки Tab.
FindObject - Поиск объекта по имени поля.

Code: Выделить всё

FINDOBJECT('Сумма')
Результат: dxCalcEdit1
SkipReadOnly - Отключает переход на поля компонентов, которые недоступны для редактирования.
ReportSave - Печать шаблона в файл.

Code: Выделить всё

REPORTSAVE('Счет.doc','Счет'+CSTR(RECNO(имя формы))+'.doc',True)

v0.04
OUTLOOKMAILSEND,THUNDERBIRDMAILSEND,MAILSEND - Отправка почты через Outlook, Thunderbird или автоматически определенный клиентом.

Code: Выделить всё

MAILSEND('user1@mail.com'+newline+'user2@mail.com', 'test', 'Приветствую. '+newline+'Тестовое письмо'+newline+'С уважением, автор.', 'C:\file1.txt'+newline+'C:\file2.txt'+newline+'file3.txt', false)

OUTLOOKMAILSENDEX,THUNDERBIRDMAILSENDEX,MAILSENDEX - Расширенный режим отправки почты через Outlook, Thunderbird или автоматически определенный клиентом.

Code: Выделить всё

MAILSENDEX('user1@mail.com'+newline+'user2@mail.com', 'cc@mail.ru', 'bcc@mail.ru', 'test', 'Приветствую. '+newline+'Тестовое письмо'+newline+'С уважением, автор.', 'C:\file1.txt'+newline+'C:\file2.txt'+newline+'file3.txt', false)

v0.05 - *REPORTSAVE - автоматическая подстановка расширения выходного файла и проверка существования файла шаблона.
v0.06 - QUOTESL и QUOTES экранирование спецсимволов в тексте для надписи и html кода.

Code: Выделить всё

QUOTESL('ТОО "Рога & Копыта"')   /* ТОО "Рога && Копыта" */
QUOTES('ТОО "Рога&Копыта"')   /* ТОО &quot;Рога&amp;Копыта&quot; */

v0.07 - *REPORTSAVE - используется штатный диалог вывода ошибок, всегда создавался файл '.doc'
v0.08 - RAWURLENCODE - Кодирование строки в URL

Code: Выделить всё

RAWURLENCODE('Проверка!')

9.04.2017Перезалил версию 0.08

v0.09 Изменен вызов ExpandFileName

v0.10 Исправлена ошибка в выражении ObjectVisible

v0.11 Добавлено выражение TIMESBETWEEN

v0.12 Добавлены выражения DLGOPENFILE, DLGSAVEFILE - возвращают путь к файлу, DLGSELECTDIR - путь к каталогу

Code: Выделить всё

DLGOPENFILE('Выбирте файл',[Текст1],'D:\','Word|*.doc;*.docx')
DLGSAVEFILE('Выбирте файл',[Текст1],'D:\','Word|*.doc;*.docx')
DLGSELECTDIR('Выбирте каталог','D:\')


v0.13 Добавлены выражения SECONDSTOTIMESTR, MINUTESTOTIMESTR - количество секунд или минут конвертирует в строку времени.

v0.14 Добавлены выражения SETMAINICONFILE, SETFORMICONFILE - Загрузка иконки в главного окна или в окно формы.

v0.15 Добавлено выражение OBJECTENABLE - Функция для управления доступностью объектов. Совместно с YurAnt.

v0.15.1 Исправлено дублирование IntToHex


Актуальная версия (01.12.2018):
neitri_v0.15.1.zip

neitri_v0.15.zip

neitri_v0.14.zip

neitri_v0.13.zip

neitri_v0.12.zip

neitri_v0.08.zip
neitri
40 Модуль ProgressBar для DataExpress Реализация WINAPI ProgressBar для DataExpress.
TProgressBar сделан на основе TParamList.
W2Fuqk6Iy4.gif

Создание
function PB_Create(Parent: TCustomControl): TProgressBar;
Parent - TCustomControl в котором будет нарисован TProgressBar.

ВНИМАНИЕ. TProgressBar нельзя создать до/во время создания окна (FormCreate/OnCreate), в котором ProgressBar будет размещен.

Пример:

Code: Выделить всё

var
ProgressBar: TProgressBar;

procedure EditWindow_OnShow(Sender: TObject);
begin
  ProgressBar := PB_Create(self.EditWindow);
end;

procedure Form_Create;
begin
  self.EditWindow.OnShow :=@ EditWindow_OnShow
end;


Уничтожение
procedure PB_Destroy(var: TProgressBar);
После уничтожения TProgressBar = nil.

ВНИМАНИЕ. Уничтожать TProgressBar до уничтожения окна в котором он расположен.

Пример:

Code: Выделить всё

var
ProgressBar: TProgressBar;

procedure EditWindow_OnHide(Sender: TObject);
begin
  PB_Destroy(ProgressBar)
end;

procedure Form_Create;
begin
  self.EditWindow.OnHide :=@ EditWindow_OnHide
end; 


Свойства TProgressBar хранятся в параметре по умолчанию Values.

Пример чтения свойства:

Code: Выделить всё

TProgressBar['Свойство']


Пример записи свойства:

Code: Выделить всё

TProgressBar['Свойство'] := Значение

Список свойств:
Height: Integer - Высота
Left: Integer - Расстояние слева
MarqueeInterval: Integer - Время в миллисекундах между обновлениями анимации, при выбранном стиле pbstMarquee.
Min: Integer - Минимальное позиция прогресса
Max: Integer - Максимальная позиция прогресса
Position: Integer - Текущая позиция прогресса
State: TProgressBarState - Состояние TProgressBar, может принимать значения: pbsNormal, pbsError или pbsPaused.
  • pbsNormal - Стандартное состояние
  • pbsError - Состояние ошибки
  • pbsPaused - Состояние приостановки
Step: Integer - Шаг позиции прогресса при выполнении 'StepIt'
Style: TProgressBarStyle - Может принимать значения pbstNormal или pbstMarquee.
  • pbstNormal - Отображает значения позиции прогресса
  • pbstMarquee - Отображает бесконечную анимацию прогресса
Top: Integer - Расстояние сверху
Orientation: TOrientation - Ориентация продвижения TProgressBar, может принимать значения pbHorizontal или pbVertical.
  • pbHorizontal - Горизонтальное продвижение
  • pbVertical - Вертикальное продвижение
Visible: Boolean - Видимость TProgressBar
Width: Integer - Ширина


Аналог процедур TProgressBar, вызываются путем чтения и записи свойств.

Процедуры без входных параметров:
  • StepIt - продвигает позицию на шаг свойства "Step"
  • Show - Делает компонент видимым
  • Hide - Делает компонент невидимым
Пример:

Code: Выделить всё

TProgressBar['StepIt']
TProgressBar['Show']
TProgressBar['Hide']


Процедуры с входными параметрами:
  • SetBounds: [X, Y, w, h] - Устанавливает границы TProgressBar, где:
    • X: Integer - Расстояние слева
    • Y: Integer - Расстояние сверху
    • w: Integer - Ширина TProgressBar
    • h: Integer - Высота TProgressBar
  • SetRange: [Min, Max] - Устанавливает минимальную и максимальную позицию TProgressBar, где:
    • Min: Integer - Минимальное значение позиции
    • Max: Integer - Максимальное значение позиции
  • StepBy: Integer - Продвигает позицию на указанное значение
Пример:

Code: Выделить всё

TProgressBar['SetBounds'] := [10, 10, 180, 30]
TProgressBar['SetRange'] := [0, 100]
TProgressBar['StepBy'] := 15


ProgressBar может не работать на некоторых версиях Windows.

[ dxdb_icon Демо онлайн ]

Camellia
41 Модуль SMART Автор: Admin
Описание: добавляет несколько новых функций
SMART_FocusColor - подсвечивает активное поле. Есть возможность задать цвет подсветки.
SMART_SetFieldValue - устанавливает значение в указанном поле в тех записях формы, которые выбрал запрос.
SMART_PivotToXls - Экспортирует сводную таблицу в Эксель.

РЕПОЗИТОРИЙ
jurist23rus
42 Модуль y_module y_module
Автор: YurAnt
Версия: v0.4
Список функций:

1. KURS_UE - получает курс валют (евро, доллар) на указанную дату из сервиса центробанка (cbr.ru)
Зависимость: плагин ds_inet.dll (будет дополняться новыми интернет-функциями. Пожелания приветствуются)
По умолчанию "из коробки" функция ищет плагин в папке с программой. (external 'KursUE@ds_inet.dll';)
Для удобства путь можно изменить путь на свой (например ПапкаDX\lib) и указать его в epas - external 'KursUE@lib\ds_inet.dll';

2. EKFOR [color=#808080](EnterKeyForOpenRec)
Функция подменяет клавишу Space на Enter для открытия формы редактирования в режиме "Только таблица".
Отдельная благодарность neitri и drts за активную помощь в создании функции
[/color]

3. QR_CODE_GEN
Функция генерирует QR-код из заданного текста и помещает в компонент "Изображение".
Зависимости: интернет и доступность сервиса http://goqr.me/
Изображение
Отдельная благодарность neitri за активную помощь в создании функции Изображение .

Скачать:
qr_code_online_generator.epas.zip

4. BtnMLCaption
Функция позволяет установить произвольный многострочный текст для "Кнопки".
Изображение
BtnMLCaption.epas.zip


Содержимое комплекта:
    y_module.epas
    ds_inet.dll
    KURS_UE_EXAMPLE.FDB
    y_module.zip


---

5. Клик - действие. Эмулирует клик левой кнопкой мыши на указанном компоненте.
Клик.zip
YurAnt
43 Модуль для работы с Telegram Bot API (Совместная разработка). Ввиду закрытости проекта решил создать отдельную ветку.
В данной теме приглашаю всех желающих (кодеров и не только) к совместному обсуждению и разработке расширения для работы с ботом Telegram через его API. Из за недостатка времени и недолгого знакомства с этими технологиями, пока сделал небольшой эскиз.
Цель: создать полностью автономный отдельный модуль, исключительно с применением PascalScript и системных функций Windows без использования сторонних библиотек и "невидимых" vpn/прокси. На его базе планируется создать пользовательскую обертку, максимально доступную для понимания и максимально простого внедрения в проекты.

Что сделано на сегодняшний день:
1. Подключение к сервису. Сделал асинхронный коннект с проверкой ответа в цикле, который не вешает программу. Прокси пока указывается вручную в параметре SetProxy.
2. Отправка сообщений боту, запрос информации о чате, запрос информации о боте (ответы пока в чистом json)

Что требуется/планируется:
1. Придумать метод перебора прокси из списка.
2. Внедрить long polling запросы.
3. Написать функцию конвертер JSON Unicode для текста вида \u04030\u04a0\\\ (кириллица).

Code: Выделить всё

function ConvStr(const InText: string): string;
var
  i, op: Integer;
  t, n: string;
  WChar:WideChar;
begin
  i := 1;
  op := 1;
  while Utf8Pos('\u', InText,i) <> 0 do
  begin
    i := Utf8Pos('\u', InText, i);
    t := t + Utf8Copy(InText, op, i - op);
    i:=i+2;
    n := Utf8Copy(InText, i, 4);
    op := i + 4;
    WChar:=(StrToInt('$'+n) as WideChar)
    t := t + WChar;
    Application.ProcessMessages;
  end;
  t := t + Utf8Copy(InText, op, Length(InText));
  Result := t;
end;

4. На базе JSON-парсера разработать TG-фреймворк с набором функций из API для удобства доступа к объектам.
5. Разработка внутреннего API и пользовательской обертки.

Коды:

Code: Выделить всё

type
  TJsonNumber = Double;
  TJsonString = WideString;
  TJsonChar = WideChar;
  TJsonWord = (JWUnknown, JWTrue, JWFalse, JWNull);
  TJsonValueKind = (JVKUnknown, JVKNumber, JVKString, JVKWord, JVKArray, JVKObject);
  TJsonValue = record
    Kind: TJsonValueKind;
    Index: Integer;
  end;
  TJsonArray = array of TJsonValue;
  TJsonPair = record
    Key: TJsonString;
    Value: TJsonValue;
  end;
  TJsonObject = array of TJsonPair;
  TJsonParserOutput = record
    Numbers: array of TJsonNumber;
    Strings: array of TJsonString;
    Words: array of TJsonWord;
    Arrays: array of TJsonArray;
    Objects: array of TJsonObject; // The root object is the first one
    Errors: array of TJsonString;
  end;
  TJsonParser = record
    At: Integer; // The index of the current character
    Ch: TJsonChar; // The current character
    Text: TJsonString;
    Output: TJsonParserOutput;
  end;
  TJsonValueParser = function (var JsonParser: TJsonParser): TJsonValue;

// Call error when something is wrong.
procedure Error(var JsonParser: TJsonParser; Msg: TJsonString);
var
  ErrorMsg: TJsonString;
  N: Integer;
begin
  ErrorMsg := Format('Error: "%s". Position: %d. Text: "%s"', [Msg, JsonParser.At, JsonParser.Text]);
  N := Length(JsonParser.Output.Errors);
  SetLength(JsonParser.Output.Errors, N + 1);
  JsonParser.Output.Errors[N] := ErrorMsg;
end;

function Next(var JsonParser: TJsonParser; C: TJsonChar): TJsonChar;
begin
  Result := #0;
  // If a non-#0 C parameter is provided, verify that it matches the current character.
  if (C <> #0) and (C <> JsonParser.Ch) then
  begin
    Error(JsonParser, 'Expected "' + C + '" instead of "' + JsonParser.Ch + '"');
    Exit;
  end;
  // Get the next character. When there are no more characters, return #0.
  if JsonParser.At > Length(JsonParser.Text) then
  begin
    JsonParser.Ch := #0;
    Exit;
  end;
  JsonParser.Ch := JsonParser.Text[JsonParser.At];
  Inc(JsonParser.At);
  Result := JsonParser.Ch;
end;

// Parse a number value.
function Number(var JsonParser: TJsonParser): Double;
var
  S: WideString;
begin
  Result := 0;
  S := '';
  if JsonParser.Ch = '-' then
  begin
    S := '-';
    Next(JsonParser, '-');
  end;
  while (JsonParser.Ch >= '0') and (JsonParser.Ch <= '9') do
  begin
    S := S + JsonParser.Ch;
    Next(JsonParser, #0);
  end;
  if JsonParser.Ch = '.' then
  begin
    S := S + '.';
    while (Next(JsonParser, #0) <> #0) and (JsonParser.Ch >= '0') and (JsonParser.Ch <= '9') do
      S := S + JsonParser.Ch;
  end;
  if (JsonParser.Ch = 'e') or (JsonParser.Ch = 'E') then
  begin
    S := S + JsonParser.Ch;
    Next(JSonParser, #0);
    if (JsonParser.Ch = '-') or (JsonParser.Ch = '+') then
    begin
      S := S + JsonParser.Ch;
      Next(JsonParser, #0);
    end;
    while (JsonParser.Ch >= '0') and (JsonParser.Ch <= '9') do
    begin
      S := S + JsonParser.Ch;
      Next(JsonParser, #0);
    end;
  end;
  if S = '' then
    Error(JsonParser, 'Bad number')
  else
    Result := StrToFloat(S);
end;

// Parse a string value.
function String_(var JsonParser: TJsonParser): TJsonString;
var
  HexDigit, HexValue: Integer;
  I: Integer;
  SpecChar: TJsonChar;
begin
  Result := '';
  // When parsing for string values, we must look for " and \ characters.
  if JsonParser.Ch = '"' then
  begin
    while Next(JsonParser, #0) <> #0 do
    begin
      if JsonParser.Ch = '"' then
      begin
        Next(JsonParser, #0);
        Exit;
      end;
      if JsonParser.Ch = '\' then
      begin
        Next(JsonParser, #0);
        if JsonParser.Ch = 'u' then
        begin
          HexValue := 0;
          for I := 1 to 4 do
          begin
            HexDigit := StrToInt('0x' + Next(JsonParser, #0));
            HexValue := HexValue * 16 + HexDigit;
          end;
          Result := Result + Chr(HexValue);
        end
        else
        begin
          case JsonParser.Ch of
            '"': SpecChar := '"';
            '\': SpecChar := '\';
            '/': SpecChar := '/';
            'b': SpecChar := #8;
            'f': SpecChar := #12;
            'n': SpecChar := #10;
            'r': SpecChar := #13;
            't': SpecChar := #9;
          else
            Break;
          end;
        end;
      end
      else
        Result := Result + JsonParser.Ch;
    end;
  end;
  Error(JsonParser, 'Bad string');
end;

// Skip whitespace.
procedure White(var JsonParser: TJsonParser);
begin
  while (JsonParser.Ch <> #0) and (JsonParser.Ch <= ' ') do
    Next(JsonParser, #0);
end;

// true, false, or null.
function Word_(var JsonParser: TJsonParser): TJsonWord;
begin
  Result := JWUnknown;
  case JsonParser.Ch of
    't':
    begin
      Next(JsonParser, 't');
      Next(JsonParser, 'r');
      Next(JsonParser, 'u');
      Next(JsonParser, 'e');
      Result := JWTrue;
      Exit;
    end;
    'f':
    begin
      Next(JsonParser, 'f');
      Next(JsonParser, 'a');
      Next(JsonParser, 'l');
      Next(JsonParser, 's');
      Next(JsonParser, 'e');
      Result := JWFalse;
      Exit;
    end;
    'n':
    begin
      Next(JsonParser, 'n');
      Next(JsonParser, 'u');
      Next(JsonParser, 'l');
      Next(JsonParser, 'l');
      Result := JWNull;
      Exit;
    end;
  end;
  Error(JsonParser, 'Unexpected "' + JsonParser.Ch + '"');
end;

// Parse an array value.
function Array_(var JsonParser: TJsonParser; Value: TJsonValueParser): TJsonArray;
var
  N: Integer;
begin
  SetLength(Result, 0); // Empty array
  N := 0;
  if JsonParser.Ch = '[' then
  begin
    Next(JsonParser, '[');
    White(JsonParser);
    if JsonParser.Ch = ']' then
    begin
      Next(JsonParser, ']');
      Exit; // Return empty array
    end;
    while JsonParser.Ch <> #0 do
    begin
      Inc(N);
      SetLength(Result, N);
      Result[N - 1] := Value(JsonParser);
      White(JsonParser);
      if JsonParser.Ch = ']' then
      begin
        Next(JsonParser, ']');
        Exit;
      end;
      Next(JsonParser, ',');
      White(JsonParser);
    end;
  end;
  Error(JsonParser, 'Bad array');
end;

// Parse an object value.
function Object_(var JsonParser: TJsonParser; Value: TJsonValueParser): TJsonObject;
var
  Key: TJsonString;
  I, N: Integer;
begin
  SetLength(Result, 0); // Empty object
  N := 0;
  if JsonParser.Ch = '{' then
  begin
    Next(JsonParser, '{');
    White(JsonParser);
    if JsonParser.Ch = '}' then
    begin
      Next(JsonParser, '}');
      Exit; // Return empty object
    end;
    while JsonParser.Ch <> #0 do
    begin
      Key := String_(JsonParser);
      White(JsonParser);
      Next(JsonParser, ':');
      for I := 0 to N - 1 do
      begin
        if Key = Result[I].Key then
          Error(JsonParser, 'Duplicate key "' + Key + '"');
      end;
      Inc(N);
      SetLength(Result, N);
      Result[N - 1].Key := Key;
      Result[N - 1].Value := Value(JsonParser);
      White(JsonParser);
      if JsonParser.Ch = '}' then
      begin
        Next(JsonParser, '}');
        Exit;
      end;
      Next(JsonParser, ',');
      White(JsonParser);
    end;
  end;
  Error(JsonParser, 'Bad object');
end;

// Parse a JSON value. It could be a number, a string, a word, an array, or an object.
function Value(var JsonParser: TJsonParser): TJsonValue;
var
  N: Integer;
begin
  Result.Kind := JVKUnknown;
  Result.Index := -1;
  White(JsonParser);
  case JsonParser.Ch of
    '-', '0'..'9':
    begin
      N := Length(JsonParser.Output.Numbers);
      SetLength(JsonParser.Output.Numbers, N + 1);
      JsonParser.Output.Numbers[N] := Number(JsonParser);
      Result.Kind := JVKNumber;
      Result.Index := N;
    end;
    '"':
    begin
      N := Length(JsonParser.Output.Strings);
      SetLength(JsonParser.Output.Strings, N + 1);
      JsonParser.Output.Strings[N] := String_(JsonParser);
      Result.Kind := JVKString;
      Result.Index := N;
    end;
    't', 'f', 'n':
    begin
      N := Length(JsonParser.Output.Words);
      SetLength(JsonParser.Output.Words, N + 1);
      JsonParser.Output.Words[N] := Word_(JsonParser);
      Result.Kind := JVKWord;
      Result.Index := N;
    end;
    '[':
    begin
      N := Length(JsonParser.Output.Arrays);
      SetLength(JsonParser.Output.Arrays, N + 1);
      JsonParser.Output.Arrays[N] := Array_(JsonParser, @Value);
      Result.Kind := JVKArray;
      Result.Index := N;
    end;
    '{':
    begin
      N := Length(JsonParser.Output.Objects);
      SetLength(JsonParser.Output.Objects, N + 1);
      JsonParser.Output.Objects[N] := Object_(JsonParser, @Value);
      Result.Kind := JVKObject;
      Result.Index := N;
    end;
  else
    Error(JsonParser, 'Bad JSON value');
  end;
end;

procedure ParseJson(var JsonParser: TJsonParser; const Source: WideString);
begin
  if Source = '' then
    Exit;
  JsonParser.At := 1;
  JsonParser.Ch := ' ';
  JsonParser.Text := Source;
  Value(JsonParser);
  White(JsonParser);
  if JsonParser.Ch <> #0 then
    Error(JsonParser, 'Syntax error');
end;

procedure ClearJsonParser(var JsonParser: TJsonParser);
begin
  JsonParser.At := 0;
  JsonParser.Ch := #0;
  JsonParser.Text := '';
  SetLength(JsonParser.Output.Numbers, 0);
  SetLength(JsonParser.Output.Strings, 0);
  SetLength(JsonParser.Output.Words, 0);
  SetLength(JsonParser.Output.Arrays, 0);
  SetLength(JsonParser.Output.Objects, 0);
  SetLength(JsonParser.Output.Errors, 0);
end;

function IndentString(Indent: Integer): TJsonString;
var
  I: Integer;
begin
  for I := 1 to 4 * Indent do
    Result := Result + ' ';
end;

procedure PrintJsonObject(const Output: TJsonParserOutput; Index, Indent: Integer; Lines: TStringList; CommaAfter: TJsonString); forward;

procedure PrintJsonArray(const Output: TJsonParserOutput; Index, Indent: Integer; Lines: TStringList; CommaAfter: TJsonString);
var
  IS0, IS1: TJsonString;
  I: Integer;
  V: TJsonValue;
  S, Comma: TJsonString;
begin
  IS0 := IndentString(Indent);
  IS1 := IndentString(Indent + 1);
  Lines.Add(IS0 + '[');
  for I := 0 to Length(Output.Arrays[Index]) - 1 do
  begin
    if I < Length(Output.Arrays[Index]) - 1 then
      Comma := ','
    else
      Comma := '';
    V := Output.Arrays[Index][I];
    case V.Kind of
      JVKUnknown: Lines.Add(IS1 + '?kind?' + Comma);
      JVKNumber: Lines.Add(Format('%s%g' + Comma, [IS1, Output.Numbers[V.Index]]));
      JVKString: Lines.Add(IS1 + '"' + Output.Strings[V.Index] + '"' + Comma);
      JVKWord:
      begin
        case Output.Words[V.Index] of
          JWUnknown: S := '?word?';
          JWTrue: S := 'true';
          JWFalse: S := 'false';
          JWNull: S := 'null';
        end;
        Lines.Add(IS1 + S + Comma);
      end;
      JVKArray: PrintJsonArray(Output, V.Index, Indent + 1, Lines, Comma);
      JVKObject: PrintJsonObject(Output, V.Index, Indent + 1, Lines, Comma);
    end;
  end;
  Lines.Add(IS0 + ']' + CommaAfter);
end;

procedure PrintJsonObject(const Output: TJsonParserOutput; Index, Indent: Integer; Lines: TStringList; CommaAfter: TJsonString);
var
  IS0, IS1: TJsonString;
  I: Integer;
  K: TJsonString;
  V: TJsonValue;
  S, Comma: TJsonString;
begin
  IS0 := IndentString(Indent);
  IS1 := IndentString(Indent + 1);
  Lines.Add(IS0 + '{');
  for I := 0 to Length(Output.Objects[Index]) - 1 do
  begin
    if I < Length(Output.Objects[Index]) - 1 then
      Comma := ','
    else
      Comma := '';
    K := '"' + Output.Objects[Index][I].Key + '"';
    V := Output.Objects[Index][I].Value;
    case V.Kind of
      JVKUnknown: Lines.Add(IS1 + K + ': ?kind?' + Comma);
      JVKNumber: Lines.Add(Format('%s: %g' + Comma, [IS1 + K, Output.Numbers[V.Index]]));
      JVKString: Lines.Add(IS1 + K + ': "' + Output.Strings[V.Index] + '"' + Comma);
      JVKWord:
      begin
        case Output.Words[V.Index] of
          JWUnknown: S := '?word?';
          JWTrue: S := 'true';
          JWFalse: S := 'false';
          JWNull: S := 'null';
        end;
        Lines.Add(IS1 + K + ': ' + S + Comma);
      end;
      JVKArray:
      begin
        Lines.Add(IS1 + K + ':');
        PrintJsonArray(Output, V.Index, Indent + 1, Lines, Comma);
      end;
      JVKObject:
      begin
        Lines.Add(IS1 + K + ':');
        PrintJsonObject(Output, V.Index, Indent + 1, Lines, Comma);
      end;
    end;
  end;
  Lines.Add(IS0 + '}' + CommaAfter);
end;

procedure PrintJsonParserOutput(const Output: TJsonParserOutput; Lines: TStringList);
begin
  PrintJsonObject(Output, 0, 0, Lines, '');
end;

////////////////////////////////////////////////////////////////////////////////
///////////////////////        TELEGRAM BOT      ///////////////////////////////
////////////////////////////////////////////////////////////////////////////////


function GetQueryStatus(const InStr:TJSonString):variant;
var  JP: TJsonParser;
S:string;
i,j:integer;
Kind:TJsonValueKind;
Res:variant;
begin
  try
  ClearJsonParser(JP);
  ParseJson(JP, InStr);
  for J := 0 to Length(JP.Output.Errors) - 1 do
  debug(JP.Output.Errors[J]);
  for i:=0 to length(JP.Output.Objects[0])-1 do
  if JP.Output.Objects[0][i].Key = 'ok' then
  if JP.Output.Objects[0][i].Value.Kind = JVKWord then
    begin
    if JP.Output.Words[JP.Output.Objects[0][i].Value.Index] =
    JWUnknown then res:=word;
    if JP.Output.Words[JP.Output.Objects[0][i].Value.Index] =
    JWTrue then res:=true;
    if JP.Output.Words[JP.Output.Objects[0][i].Value.Index] =
    JWFalse then res:=false;
    if JP.Output.Words[JP.Output.Objects[0][i].Value.Index] =
    JWNull then res:=null;
    end;
    except
    debug('JsonParser: '+ExceptionToString(ExceptionType,ExceptionParam));
    exit;
    end;
    result:=res;
end;

Code: Выделить всё

{$i koldev_jsonparser}


//  \u0000 to S  // ЧТО ТО В ЭТОЙ ФУНКЦИИ НЕ ТО!!! Переполняет память.
function ConvStr(const InText: string): string;
var
  i, op: Integer;
  c: Char;
  t, n: string;
begin
  i := 1;
  op := 1;
  while Utf8Pos('\u', InText,i) <> 0 do
  begin
   i := Utf8Pos('\u', InText, i);
   t := t + Utf8Copy(InText, op, i - op);
   i:=i+2;
   n := Utf8Copy(InText, i, 4);
   n:=Utf8ToWinCP(n)
   op := i + 4;
   c := Chr(StrToInt('$' + n)-848);
   t := t + WinCPToUtf8(c);
   n:='';
  end;
  t := t + Utf8Copy(InText, op, Length(InText));
  Result := t;
end;

        // Попытка сделать свой костыль.
const cyr_chars =
'\u0430 = а; \u0410 = А;'+
'\u0431 = б; \u0411 = Б;'+
'\u0432 = в; \u0412 = В;'+
'\u0433 = г; \u0413 = Г;'+
'\u0434 = д; \u0414 = Д;'+
'\u0435 = е; \u0415 = Е;'+
'\u0451 = ё; \u0401 = Ё;'+
'\u0436 = ж; \u0416 = Ж;'+
'\u0437 = з; \u0417 = З;'+
'\u0438 = и; \u0418 = И;'+
'\u0439 = й; \u0419 = Й;'+
'\u043a = к; \u041a = К;'+
'\u043b = л; \u041b = Л;'+
'\u043c = м; \u041c = М;'+
'\u043d = н; \u041d = Н;'+
'\u043e = о; \u041e = О;'+
'\u043f = п; \u041f = П;'+
'\u0440 = р; \u0420 = Р;'+
'\u0441 = с; \u0421 = С;'+
'\u0442 = т; \u0422 = Т;'+
'\u0443 = у; \u0423 = У;'+
'\u0444 = ф; \u0424 = Ф;'+
'\u0445 = х; \u0425 = Х;'+
'\u0446 = ц; \u0426 = Ц;'+
'\u0447 = ч; \u0427 = Ч;'+
'\u0448 = ш; \u0428 = Ш;'+
'\u0449 = щ; \u0429 = Щ;'+
'\u044a = ъ; \u042a = Ъ;'+
'\u044b = ы; \u042b = Ы;'+
'\u044c = ь; \u042c = Ь;'+
'\u044d = э; \u042d = Э;'+
'\u044e = ю; \u042e = Ю;'+
'\u044f = я; \u042f = Я;';

function J2Decode(InTxt:string):string;
var txt,s,s1,lw,rw:string;
SL:TStrings;
i:integer;
begin
if InTxt='' then exit;
SL:=TstringList.Create;
SplitStr(cyr_chars,';',SL);
for i:=0 to SL.Count-1 do
begin
  s1:=Trim(SL[i]);
  lw:=Trim(Utf8Copy(s1,1,Utf8Pos('=',s1,1)-1));
  rw:=Trim(Utf8Copy(s1,Utf8Pos('=',s1,1)+1,Length(s1)-Utf8Pos('=',s1,1)));
  txt:=Utf8StringReplace(txt, lw, rw,[rfReplaceAll])

end;
result:=txt;
SL.Free;
end;

function ReplaceAll(Text,OldTxt,NewTxt:String):string;
begin
result:=Utf8StringReplace(Text,OldTxt,NewTxt,[rfReplaceAll])
end;

procedure Sleep(ms:cardinal);
external 'Sleep@kernel32 stdcall';


{---------------------------------------------------------------}

const
Token = '677398564:AAFPeLGgGs2x7tLaC-ahvZwzCnu_f_RXZfE';

var HttpReq,xDoc:variant;
T:TTimer;

procedure CreateHTTP(Sender: TObject);
begin
try
//HttpReq:=CreateOleObject('MSXML2.ServerXMLHTTP'); // доработать автоопределение.
HttpReq:=CreateOleObject('WinHttp.WinHttpRequest.5.1');

HttpReq.SetTimeouts(5000,5000,5000,5000); // доработать в параметры
HttpReq.setProxy(2,'125.141.200.39');  // доработать перебор.
except
debug(ExceptionToString(ExceptionType,ExceptionParam));
end;
end;

procedure SetCursorPos;
begin
dxMemo1.SetFocus;
dxMemo1.SelStart:=Length(dxMemo1.Text)-20;
end;

function SendRequest(utl:string):string;
var S:string;
i,rs:integer;
wfr:boolean;
begin
Self['Поле приема']:=''
S:=ReplaceAll(VarToStr(utl),#13#10,'%0A');
S:=ReplaceAll(S,#42,'%2A');
HttpReq.open('post',S, true);
HttpReq.send;
i:=1;
dxLabel1.Caption:='Выполняется запрос.'

repeat
wfr:=HttpReq.WaitForResponse(5);
inc(i)
Sleep(50);
dxLabel1.Caption:='Выполняется запрос.'+StringOfChar(#46,i);
application.ProcessMessages;
 until
((wfr=true) or (i>10))

{  repeat
    rs:=HttpReq.ReadyState;
    inc(i)
    Sleep(100);
    dxLabel1.Caption:='Выполняется запрос.'+StringOfChar(#46,i);
    application.ProcessMessages;
  until
((HttpReq.ReadyState=4) or (i>100));
}
result:=
//J2Decode(
HttpReq.ResponseText
//)
;
dxLabel1.Caption:='ОК'
end;


procedure CloseHTTP(Sender:TObject);
begin HttpReq:=Unassigned; end;

{***************************************************************************}


///////////////

function ParseUpdates(InStr:string):string;
var
  Source, Lines: TStringList;
  JsonParser: TJsonParser;
  I, J: Integer;
  S,SS:string;
begin
try
    Source := TStringList.Create;
    Source.Text:=InStr;
    ClearJsonParser(JsonParser);
    ParseJson(JsonParser, Source.Text);
    Source.Free;
    for J := 0 to Length(JsonParser.Output.Errors) - 1 do
      debug(JsonParser.Output.Errors[J]);
    Lines := TStringList.Create;
    for i:=0 to GetArrayLength(JsonParser.Output.Strings)-1 do
    begin
    if i=0 then
    Lines.Add(JsonParser.Output.Strings[0])
    else
     if i>0 then
      if Trim(JsonParser.Output.Strings[i-1])='private' then
    Lines.Add(JsonParser.Output.Strings[i])
    end;
    result:=Lines.Text;
    Lines.Free;
except
debug(ExceptionParam)
end; end;


//////////////

procedure getUpdates(Sender:TObject);
begin
dxMemo1.Text:=
//ParseUpdates(
//j2decode(
SendRequest('https://api.telegram.org/bot'+Token+'/getUpdates')
//)
//)
SetCursorPos;
end;

procedure getUpdates2(Sender:TObject);
begin
dxMemo1.Text:=
j2decode(
SendRequest('https://api.telegram.org/bot'+Token+'/getUpdates')
)
SetCursorPos;
end;


procedure SendMessage(Sender:TObject);
var QueryResponse:string;
begin
try
QueryResponse := SendRequest('https://api.telegram.org/bot'+Token+'/sendMessage?chat_id=671190259&text='+
VarToStr(Self['Поле отправки']));
if GetQueryStatus(QueryResponse) then
begin
dxMemo1.Text:='ОК: ' + #13#10#13#10 + QueryResponse;
SetCursorPos;
end;
except
dxMemo1.Text:=ExceptionParam;
end;
end;

procedure DeleteMessage(Sender:TObject);
begin
dxMemo1.Text:=
SendRequest('https://api.telegram.org/bot'+Token+'/DeleteMessage?chat_id=671190259&message_id='+
VarToStr(Self['id сообщения']))
SetCursorPos;
end;

procedure getMe(Sender:TObject);
var QueryResponse:string;
begin
QueryResponse := SendRequest('https://api.telegram.org/bot'+Token+'/getMe');
if GetQueryStatus(QueryResponse) then
begin
dxMemo1.Text:='ОК: ' + #13#10#13#10 + QueryResponse;
SetCursorPos;
end
 else
dxMemo1.Text:='Что то пошло не так';
end;

procedure Test(Sender:TObject);
begin
debug(J2Decode('u0442\u0435 u0441\u043b\u0435'))
end;

procedure  GetStatus(Sender:TObject);
begin
try

if not (VarIsNull(HttpReq)) then
if not (VarIsNull(HttpReq.Status)) then
//debug(HttpReq.Status);
getUpdates(Sender);

except
debug(ExceptionParam)
end;
end;


procedure Form_Create;
var s:string;
begin
//T:=TTimer.Create(Self);
//T.Interval:=5000;
//T.OnTimer:=@GetStatus;
dxLabel1.Caption:=''
Self.OnAfterOpen:=@CreateHTTP;
dxButton1.OnClick:=@getUpdates;// getUpdates;
dxButton2.OnClick:=@SendMessage;
dxButton3.OnClick:=@getMe;
end;

procedure Form_Destroy;
begin
CloseHTTP(Self)
end;

dxdb_icon Тестовая база

Логика работы бота (работы бота :lol: ):
Судя по данным от клиентов:
auth.jpg

как и предполагал, from.id и chat.id это уникальный идентификатор пользователя и переписки с ботом одновременно.
Логику вижу примерно такую:
1. Пользователь отсылает боту любое сообщение,
чтобы это не превратилось в "ddos атаку" бот это "терпит" попыток 20 30, потом "заваливает" пользователя по его id командой kickChatMember (на некоторое время или до 31.12.9999 г.)
2. Для порядка программа на любой запрос незнакомого пользователя отвечает предложением выполнить команду /запрос на регистрацию
3. Пользователь нажимает /запрос на регистрацию и пошел процесс "знакомства".
4. После команды регистрации бот видит что пользователя с таким ID нет в "регистратуре" и "заводит на него новую карточку", туда же вносит %FirstName%, %LastName%, %WhoInThisLife% и так далее, но вся эта информация дополнительная, а главный ID. Именно по ID с у бота пользователем будет происходить общение весь срок "дружбы", независимо от устройства с которого тот выходит. После запроса на регистрацию при следующих повторных попытках бот также проверяет регистратуру и отвечает абону: "В курсе уже! Жди!"

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

Регистрация завершена. В дальнейшем пользователь может общаться с ботом в рамках выданных ему прав, но об этом позже.

Удаление пользователя может происходить двумя способами:

1. Админ устанавливает флажок "удален" и флаг "разрешить дружбу" снимается. Это можно пригодиться в том случае, когда желательно сохранить данные для (возможного) последующего использования.
2. Физическое удаление записи с пользователем, если его данные более не требуются.

В обоих случаях опционально можно применить правило "анти ddos", описанное выше.


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

Если база сетевая:

Code: Выделить всё

if (GetCurrentDatabase[2] <> ':') then


Пробуем проверить соединение запросом чего нибудь от сервера:

Code: Выделить всё

function CheckDBConnect:boolean;
begin
  try
      result:=SQLSelect('select version from dx_version').Field[0].AsBoolean;
  except
      result:=false;
  end;
end; 


Если коннект оказался успешным, продолжаем штатную работу, иначе

:| непонятно что иначе. Можно попробовать выполнить перезапуск:

Code: Выделить всё

ShellExecute('open', Application.ExeName, GetCurrentDatabase (+ параметры), '',10)


и "убить себя" Application.Terminate, предварительно отправив клиенту "предсмертную записку" с сообщением о попытке "реинкарнации" в "новом теле".

Конечно такой способ прокатит, только если бот полностью автоматически стартует при запуске иначе после самоубийства он просто попадет в преисподнюю.
Если бот стартует в другом запущенном экземпляре программы, то соответственно у него начнется "раздвоение личности":Изображение
Гocть
44 Модуль напоминаний о событиях Решил поделиться своим творением, писал для своих нужд. Сразу оговорюсь, на гуру программирования я не тяну, поэтому тапками не бить, а советам буду рад. :)
Итак, Данное расширение подключается в действиях при запуске, предварительно нужно создать форму для хранения напоминаний (пример на скрине).
В выражениях добавятся соответствующие функции, для добавления напоминаний через выражения.

dxdb_icon Демо

Vofka18
45 Модуль форматирования полей "Число" и "Дата" Последняя версия: 2.2 от 31.08.18 г.

Модуль служит для организации визуального форматирования чисел в полях типа «Число» и упрощения ввода данных в поля «Дата».

РЕПОЗИТОРИЙ
jurist23rus
46 Нажимаем нужную кнопку запроса Довольно простой, но меня выручает во многих ситуациях. Раньше этот скрипт обсуждался уже. Сейчас допилил под свои нужды. Может быть кому-то пригодиться.

Code: Выделить всё

 {@action
Id=D854ACB6-91B9-4294-9740-2312CB8E9009
OrigName=SW_GridBtnClick
Name=Нажатие кнопки запроса
Group=Admin
UI=
<ui>
 <query name="_mycmp" caption="Выберите запрос"/>
 <list name="_myList" caption="Выберите кнопку" Items="Добавить;Редактировать;Удалить;Перейти;Обновить"/>
 <checkbox  name="lastExpr" caption="Перейти к последней записи"/>
</ui>
Description=Нажатие необходимой кнопки в запросе.
@}



procedure SW_GridBtnClick(QueryName:variant;It:string;Lex:boolean);
var
   QGrid:TdxQueryGrid;
   Qi:integer;
   begin
if It = 'Добавить' then Qi:=0
  Else
if It = 'Редактировать' then Qi:=1
  Else
if It = 'Удалить' then Qi:=2
  Else
if It = 'Перейти' then Qi:=4
  Else
if It = 'Обновить' then Qi:=6;
    QGrid:=Self.Queries[QueryName];
    QGrid.PopupMenu.Items[Qi].Click;
if Lex = true then QGrid.movelast;
end;
SirWolf
47 Настройка панели кнопок в главном окне Действие запуска. Позволяет выполнить кастомные настройки панели кнопок
главного окна программы.


Изображение

Возможности и опции текущей версии:

Опция позволяет изменить размер иконок до размера, указанного в списке.
Изображение
Устанавливает внутренний отступ от иконки до края кнопки и в сумме с размером иконки определяет итоговый размер кнопки на панели.
(Т.е расчет: иконка = 16px + отступ = 4px (*2) = 24px)
Изображение
Скрывает кнопки навигации для всех форм, кроме "Только форма" (т.к. в этом режиме они логически необходимы)
Изображение
Перемещает панель кнопок в форму. Примерный вид:
Изображение
Устанавливает фоновый цвет панели. Доступны цвета:
  • Системный (по-умолчанию)
  • Белый
  • Серебряный
  • Желтый
  • Кремовый
Изображение
При включенной опции панель кнопок очерчивается границей по периметру.
Изображение
new:
Опция позволяет указать путь к папке с иконками. (При указании каталога - игнорируются встроенные иконки и папка должна содержать весь набор!) Имена иконок должны соответствовать определенным индексам (пример набора иконок в приложенном архиве). Рекомендуется устанавливать размер иконок соответствующим разрешению либо кратным числу 2 (например иконки размером 32px желательно уменьшать до 16, а иконки 48px - до 24 или 12px соответственно).
Изображение

Примечание: панель кнопок в режиме "Простая форма" при подключенном расширении скрывается и опция "показать" отсутствует за ненадобностью...

В следующих версиях:
- Встроенные наборы иконок.
- Установка собственных иконок из файла
- Кнопка "Скопировать"
- (может быть) Управление видом фильтра при его изменении, кнопка сброса фильтра


---
Пожелания, предложения?



[ Скачать ]


Develop-Soft
48 Обработка массивов Модуль обработки текстовых массивов.

Функции:

A_ROUNDTO выполняет округление числа (текстового массива чисел, с разделителем ";") до указанного количества знаков после запятой.
A_DATE выполняет преобразование даты (текстового массива дат, разделенных точкой с запятой ";") вида 2018-11-27 в 27.11.2018
Изображение
Обе функции рекомендуются для обработки данных запроса, полученных методом "Соединить" и "Соединить все" (создается вычисляемое поле, в нем применяется функция, реальное поле скрывается в настройках).

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

Скачать:
Обработка массивов.zip
Гocть
49 Отрицательные числа красным цветом Действие формы. Устанавливает для всех числовых полей текущей формы (родительской или подчиненной) условное форматирование: "отрицательные числа красным шрифтом".
Раскраска при использовании этого модуля работать НЕ будет!
screen.JPG

Отрицательное красным.epas.zip

версия с исправлением от 27.08.2018
Гocть
50 Очень простые расширения от Kiss'a
TabVis.zip
Управление компонентом "Закладки" на форме.
- (группа: Компоненты форм)
TabVis - Скрывает Закладку, если условие ЛОЖЬ, Показывает обратно, если условие ИСТИНА
Параметр 1 - Текст - Имя компонента (конкретной закладки)
Параметр 2 - Условие
TabVis('dxTabSheet1',[Число]=1)
-
TabAct - Активирует Закладку, если условие ИСТИНА
Параметр 1 - Текст - Имя компонента "Закладки"
Параметр 2 - Текст - Имя компонента (конкретной закладки)
Параметр 3 - Условие
TabAct('dxPageControl1','dxTabSheet1',[Число]=1)
-
Random.zip
Генератор случайных чисел.
- (группа: Математика)
Rand - Возвращает случайное число
Параметр 1 - Число - От
Параметр 2 - Число - До
Rand(1,10)
-
FileEXT.zip
Извлекает из пути к файлу его расширение.
- (группа: Текст)
FExt - Возвращает расширение файла
Параметр 1 - Текст - Путь к файлу
FExt('D:\Моя.любимая_песя.mp3')
Результат - текст - .mp3
-
ЗЫ. Все эти функции просто выведены из движка без наворотов и проверок. Я не мастер писать скрипты (извинити-простити), но эти расширялки как-то пригодились и до сих пор работают)) Может пригодятся еще кому-нибудь.
Kiss
51 Очистка фильтра формы по нажатию кнопки Действие (action) - очистка фильтра формы по нажатию кнопки
Автор: drts
Версия: 1.0 от 12.03.2018 г.
Добавляет действие в группу поиск и фильтрация, позволяющее очистить все установленные фильтры в форме (включая дочерние)
drts
52 Периодический нумератор Действие формы.
Нумератор с настраиваемыми параметрами в пределах: Год; Квартал; Месяц; Неделя; День или сквозная нумерация (также срабатывает, если не указана дата). Имеется опция блокировки полей "Номер" и "Дата" (защита от изменений и ввода "задним числом")

Периодический нумератор_v0.2.zip


Периодический нумератор (0.1).zip
Develop-Soft
53 Поиск и отображение дубликатов записей Находит и показывает дубликаты записей (повторяющиеся записи) на форме. В настройках кнопки нужно выбрать поле, по которому будет происходить поиск. jurist23rus
54 Поиск по всем полям во всех формах Изображение

Возможности:

1) фильтр по всем видимым в Grid формы полям (выбрать поля для поиска или для исключения из поиска можно в "действия формы" )
2) значения фильтра формы учитываются
3) ESC-очистить поле поиска, Ctrl+F в grid формы-фокус в окно поиска
4) сохранение истории поиска для каждой формы отдельно
5) нажатие правой кнопкой мышки на "X" - единоразовый поиск без учета фильтра формы
6) настройка задержки старта поиска после ввода (актуально при больших объемах информации или медленном соединении с базой)
7) кнопка вниз на поле поиска - переход на grid формы, кнопка вверх в grid формы при выделенной первой строке - переход в поле поиска
8) на простой форме: значения поиска записывается в переменную kok80.QueryFilter (название переменной можно задать в настройках), форма обновляется.
Пример использования в фильтре запроса на простой форме: [?!адрес]==GetVar("kok80.QueryFilter")
9) Поиск в окне списка объекта с учетом фильтра объекта

Установка:
после импорта модуля выполнить: дизайнер - действия при запуске - вставить действие - поиск

Известные ошибки/недоработки:
- в дереве при выборе неверхней node отображает пустой результат поиска
ps здесь всегда ссылка на последнюю версию:

kok80-poisk2.10.zip [ Изображение Скачать ]

................................
dxdb_icon Демо онлайн
dxdb_icon Демо онлайн 2


Замечания, предложения ?

...
kok80
55 Приложение "DX Модули" Это отдельное приложение, основная цель которого собрать все модули в одном месте для удобства их использования и поддержки.

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

- для добавления (обновления) модуля нужна простая регистрация (только адрес электронной почты и любой логин) - это сделано, чтобы контролировать манипуляции с модулями. Пользовательская работа с модулями (установка, обновление, удаление) не требует никаких регистраций.
- любой модуль должен содержать раздел {@module ... @}
- для идентификации модуля нужно указывать его ModuleID (это обычный GUID) в разделе {@module ... @};
Например:

Code: Выделить всё

{@module
Author=Павел Дуборкин
Version=1.3
Description=Видимость/доступность компонентов по условию.
ModuleID=e14082d7-d5f9-4256-bd55-716e93582457
@}


Только для Windows, от Vista и выше.


Для установки нужно перейти по ссылке и следовать инструкциям.
- установка корректно работает только из штатных браузеров Windows (Internet Explorer, Edge).
(В Opera точно будет ошибка, в остальных не проверял)
- при установке будет дополнительно поставлен Net Framework 4.7.2, иначе работать не будет.
- запуск через ярлык на рабочем столе или в меню пуск;
- удаление через системную утилиту "Установка и удаление программ".
jurist23rus
56 Просмотр данных в браузере Модуль позволяет просматривать данные в браузере на любом устройстве. Состоит из двух действий при запуске.

1. Запуск веб-сервера.
Действие запускает веб-сервер, обеспечивает работу остальных действий модуля, отображает стартовую страницу. Стартовая страница содержит ссылки на отображаемые в браузере запросы.
Порт - порт, используемый веб-сервером. По умолчанию 80. Убедитесь, что порт разрешен брандмауэром.
Стартовая страница - произвольный текст, который должен быть введен в адресной строке браузера для доступа к странице. Например, если значение равно: /MyData/index.html, то адрес может выглядеть так: http://127.0.0.1/MyData/index.html.
Заголовок отображается на стартовой странице.

2. Просмотр запроса в браузере на мобильном устройстве.
Расширение позволяет просматривать данные запроса в браузере. Страницы адаптированы для просмотра на мобильном устройстве: смартфоне или планшете. Данные отображаются в открытой части и закрытой (в подробностях). Чтобы посмотреть подробности, коснитесь изображения глаза. Если дважды тапнуть по экрану, появится панель итогов и кнопки для доступа к фильтру и перехода на стартовую страницу. Если повторить действие, то панель и кнопки исчезнут. Чтобы отфильтровать данные, нажмите кнопку фильтра. Введите параметры и нажмите кнопку "Применить". Вместо разделителей даты, времени и дробной части числа можно вводить пробел.

При первом обращении к странице создается сессия. Если в течении 15 минут не было обращений к серверу, то сессия закрывается. При следующем открытии сессии фильтр будет иметь значения по умолчанию.

Путь - произвольная строка, которая вводится в адресной строке браузера для доступа к запросу. К примеру если значение равно: mydata, то строка в браузере может выглядеть так: http://127.0.0.1/mydata. Путь не должен содержать вопросительный знак.
Форма - форма, где расположен запрос.
Запрос - запрос, данные которого будут отображены в браузере.
Максимальное количество записей - число записей, отображаемых в браузере. Если фактическое количество записей больше, то в конце списка будет соответствующая надпись.
Поля запроса - поля запроса, отображаемые в видимой части.
Поля в подробностях - поля запроса, отображаемые в скрытой части.
Поля итогов - поля формы, значения которых будут показаны, если дважды тапнуть по экрану.
Поля фильтра - поля формы, используемые для фильтрации запроса и отображаемое на странице фильтра.
Обязательное - поле фильтра может быть обязательное для ввода.

Изображение Изображение Изображение Изображение

1.1 - внесены правки для совместимости с DataExpress от 31.03.2019.
1.0 - первая версия

WebExt.zip

dxdb_icon Демо онлайн
admin
57 Работа с регистрами 1. Копировать в регистр
Расширение копирует данные формы и ее подчиненные данные в другую форму, называемую регистром. Это позволяет решать некоторые задачи, в которых имеется три уровня подчиненности данных: Операция->Изделие->Комплектующее, Меню->Блюдо->Продукты, Операция->Услуги->Работы, материалы и т. д. Возможности запросов ограничены, они могут извлекать данные только из двух уровней подчиненности: формы и таблицы. Но если в таблице есть объекты, которые имеют какой-то состав (например, изделие состоит из комплектующих), то запрос не может получить этот состав. Для этого приходилось связывать формы запросами и использовать свойство объекта "Заполнить таблицу". Вместо этого можно просто копировать нужные для анализа данные в отдельную форму и использовать простые запросы для получения результатов. При этом интерфейс программы заметно упростится, т. к. будет избавлен от лишних элементов.

Для того, чтобы легче было разобраться с настройками действия сделал такой сводный рисунок на примере демо-базы.
REGISTERDEMO.png

2. Записать в регистр остатков
Реализация хранения итогов в форме, называемой регистром остатков. С помощью этого действия вы сможете, к примеру, вычислять остатки товаров на текущий момент. Это альтернатива вычислению остатков с помощью запроса. Запросу приходится каждый раз просматривать таблицы, чтобы вычислить остатки. Если данных много, это может занимать некоторое время. В регистре остатки уже рассчитаны и их получение происходит практически мгновенно. Расчет остатков происходит при сохранении и удалении записей. Действие ищет в регистре соответствующую запись и меняет в ней числовое поле: увеличивает или уменьшает значение в зависимости от выбранной операции. Если запись не найдена, то она добавляется. Действие может предупреждать об отрицательных остатках. Предупреждение отображается в окне вывода.

1.1 - добавлено действие "Записать в регистр остатков".
1.0 - первая версия.

Registers.zip
admin
58 Раскраска выбранным цветом 1. Действие формы "Выбрать цвет из списка". Добавляется возможность выбрать цвет из списка. В табличной части формы цвет отображается в ячейке или окрашивается вся строка.
2. Действие формы "Раскрасить запрос". Отображение выбранных цветов в запросе.

dxdb_icon Демо онлайн
admin
59 Расчетная форма Реализация функционала, как в этом видео. Есть некая форма, в которой пользователь свободно редактирует какие-то параметры (например работы/услуги) и в таблице считается итог. admin
60 Расширение Label в стиль ссылки + выражение при клике Расширение формы. Подсвечивает список Label в стиль ссылки голубым цветом, выводит подчеркивание и изменение цвета при наведении. Возможность прикрепить выражение при клике. Если есть уже прикрепленные скрипты к данной лейбе они будут выполнены. Третий параметр указывает выполнять сначала скрипт или выражение в расширении.

Обновлена версия 1.1: исправлена ошибка при многоразовом закрытии открытии набора данных и одновременном вызове формы в разных окнах.

В комплект к данному расширению добавлю функцию Переход на форму (из любого типа ViewType), в комплекте может быть создано полноценное меню на форме.
Иван
61 Расширение SQL Tree + календарь Добрый день. Пишу расширение меню поиска методом формирования SQL запроса со всеми параметрами, для случая больших БД (добавление всевозможных фильтров, полей поиска, чекбоксов, деревьев групп и т.д.). Есть ошибка которую никак не могу отловить. Если на форме "календарь" открыть один раз форму то все хорошо. При повторном открытии возникает ошибка, скрин прикрепил. Ошибка возникает если установлена галочка для создания деревьев групп. Если только календарь создавать то ошибки нет. Возможно подскажете где искать.

В базу было добавлено 500 тыс. записей для проверки скорости работы потому добавляю ссылкой на дропбокс.

По ссылке рабочий вариант расширения на демо базе уже без ошибок. Как нормально описание сделаю выложу отдельно. Пока что на примере думаю кому нужно разберутся.
.....................................................................
Обновлена версия модуля в примере от 15.04.2020

(совместим с пред версией, можно просто заменить текст скрипта и заполнить те поля что появились (добавлено возможность выбора полей в таблице, ранее они должны были быть таким же названием что и поле источник и их не выбирали))
https://www.dropbox.com/s/oid8dhv0fa9me ... O.rar?dl=0

Добавлено дополнительные возможности фильтрации (в SQL прописывая дополнительный фильтр для полей сравнений), исправлено ошибки, ускорена работа, добавлено детальное описание большинства пунктов.
Иван
62 Расширение генератор штрихкода и QR-кода Расширение для кнопки. Создан на основе библиотеки что поддерживает все типы штрихкода zint_win32_2.8.0. Расширение работает автономно. Код написан по примеру функции "Генератор QR-кода offline". Добавлено ряд настроек внешнего вида.

При первом запуске будет создана утилита [Каталог-DataExpress]\ext\Barcode\BarcodeZint.exe. В процессе генерации изображения будет создан временный файл картинки в папке temp пользователя Windows. После его загрузки в базу он будет удален.

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

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

Версия 1.3 - исправлена ошибка возможности настройки расширения после обновления версии ДХ.

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

Demo
https://www.dropbox.com/s/4ja6ihx22uu7b5i/DEMO_Barcode.FDB?dl=0
Иван
63 Расширение Меню компонента + регистр радиокнопок + видимость и доступность Расширение для создания выпадающего меню для любого компонента формы из произвольным уровнем вложенности. Работает в любом типе FormView. Основные возможности: создать кнопки и радиокнопки. Добавление картинок из галереи. Записать выражение при клике на кнопку или изменении значения радио кнопки. Возможно добавить быстрые клавиши (если для двух меню на одной форме выбрать одинаковую комбинацию будет выполнена первая в списке). Чекбокс "Скрипт" - выполнить скрипт или действие что уже прикреплено, иначе будет занулено. Актуально если прописываем название уже существующей в меню кнопки. Если заполнить все поля после таблиц "регистр", значения радиокнопок будет сохранятся в регистр для конкретного пользователя и при открытии формы их подставлять. При изменении значений радио кнопок значения будут перезаписаны в регистре.

Версия 1.1: исправлена ошибка кастумной сортировки.

Версия 1.2:
- добавлено возможность создать меню радиокнопок соответствующих столбикам запросов или таблиц, включать или отключать их видимость переключая радиокнопку (чекбокс: добавить в меню видимость колонок по значению радиокнопки.).
- значения видимости пишет регистр.
- в меню добавляет только те пункты меню что по умолчанию оставлены видимыми при настройке.
- видимость кнопок меню по значения выражения. Работает только на запросах.
- к видимости и доступности компонентов формы по значению радиокнопки добавлено Только чтение.
Иван
64 Расширение обновление запросов при переходе на закладку Расширение формы. Что бы ускорить открытие формы запросы на вкладках ставите в
ручное обновление (кроме первой на которой будет открывать по умолчанию). Расширение обновляет запросы на активной закладке при переходе. Можно выбрать отображать анимацию обновления или нет. Если на закладке несколько запросов анимация будет показана на одном запросе.

Версия 1.4: исправлена ошибка при многоразовом закрытии открытии набора данных и одновременном вызове формы в разных окнах. Ускорена работа. Обновляет все запросы на закладке.

Версия 1.5: добавлено возможность работы на простой форме. При переходе по записям в режиме таблица + форма активна первая закладка. Картинки декодирует из строки один раз при первом обновлении.
Иван
65 Расширение открывать формы для запроса нескольких источников Расширение открывает выбранную в настройках расширения форму при клике на выбранный столбик. Для открытия необходимо указать какие поля на форме и в запросе сравнить что бы найти целевую запись.

Доработка:
Версия 1.1:
Открывает форму не на одиночный, а на двойной клик.
Иван
66 Расширение резиновое поле (несколько полей) Расширение для работы с большими текстами или экономии на размере записей если диапазон длины текста может быть от очень мелкого до огромного. Для работы расширения на форме нужно поле dxMemo, таблица и в ней dxMemo. Эти объекты добавляем в расширение. Указывая размер dxMemo на форме 100 символов и такой же размер в таблице (можно указать и больше но нет особого смысла), при сохранении записи в таблицу будет писать записи по 100 символов пока не запишет весь текст. При открытии формы будет создано виртуальное TMemo и в него скопирует суммарный текст всех записей таблицы. Дальше мы фактически работаем в нем). На форме можно создать произвольное количество таких полей.

Если задать один/оба предпоследние параметры в настройках (ширина и высота) то при клике на Memo будет изменение ширины и/или высоты. При повторном клике вне области Memo размер будет возвращен. Пока мы редактируем с ресайзом другие поля добавленные в расширения будут недоступны для редактирования.
При сохранении записи в поле dxMemo будет записан текст по размеру равному количеству символов что можно в него записать (для удобства просмотра в запросах). Если текст не был изменен то записи в таблице не будет перезаписывать, это особенно ощутимо на записях свыше нескольких сотен тыс. символов.
Галочка скрыть таблицы - скрывает таблицы для пользователя.

Работа со всеми типа TipeView (кроме простой формы, только форма).

Обновление 1.4:
- Если нужно записать из скрипта текст в поле мемо на котором подключено расширение, передаем его в Params с именем равным имени поля_put.
- Если нужно добавить текст к уже существующему имя поля_add .
- Если нужно вернуть текст записанный в мемо - имя мемо_get.

(если сохраняя запись существует один из Params описанных выше будет брать данные из них, после этого зануляет).
Пример:

Code: Выделить всё

T.OpenRecord(114);
T.Edit;
T.Params['Заметка60_add']:= LongStr; // добавили текст к уже существующему
T.Post;
NewLongStr:= T.Params['Заметка60_get']; // забрали результат
T.Free;


Модуль написан по примеру кода пользователя Гость Пример: "Резиновое" текстовое поле.

Обновление 1.5:
По примеру модуля добавлена Вставка текста в место нахождения курсора на виртуальных полях.

Обновление 1.6:
Добавлена возможность получения доступа к тексту мемо используя Getvar(имяполя_get). Для срабатывания вычислений необходимо на форме
добавить dxLabel и выбрать его в расширении (который считает количество символов). Именно при вычислении количества символов одновременно происходит перезапись Getvar и
вычисление всех полей где есть Getvar(имяполя_get).
Иван
67 Расширение файловая система HTTP + LOCAL Добавлено обновление 1.2:
а. введена функция для считывания CMD ipconfig, а именно получения IP, шлюз, маска сети ПК на котором запускаем клиент. Если данные соответствуют серверу возвращает true.
б. добавлена возможность заполнять свойства сервера в настройках расширений.
в. для работы в сложных сетях добавлено свойство IPlocal (локальный IP ПК в вашей сети на котором запущен сервер). Для работы необходимо создать на сервере в папке установки ДХ файл метку с именем равным IP (пример: 99.999.999.99.txt). Смотрите пример БД.

Расширение состоит из двух модулей, один для сервера, второй для клиента. Так же дополнительно форма с описанием (+ она хранит картинки для кнопок меню запроса). И сама форма файлов. Прикрепил пример БД.

Сервер FilesServerHTTP (действие при запуске)

Cистема отправки/получения/удаления/обновления файлов на сервере через протокол HTTP.

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

Следующие Функции делают оверрайд над заполненными параметрами в настройках расширений.
SDefBase - корневая папка на сервере для хранилища файлов. Выше нее будут создаваться все папки хранилища.
SDefIP - статический IP или ddns.
SDefIPlocal - IP сервера в вашей сети (может совпадать с IP если не используете роутер).
SDefMask - маска сети сервера.
SDefG - Gateway шлюз сервера.
SDefAPIKey - ключ доступа (произвольный пароль, числа и буквы, без пробелов).
SDefPort - порт (он должен быть свободен и доступен на сервере, иначе выдаст предупреждение). Если сервер включен через роутер, что скорее всего так и есть, нужно сделать проброс порта.
ApiKey - ключ доступ.

b. Расширение будет запущено на клиенте что включен на ПК с параметрами:
а. Соответствуют параметры IP, маска сети, шлюз настройкам сервера и в папке ДХ существует файл метка с именем равным IP (пример: 99.999.999.99.txt).

б. Клиент DX запустил пользователь под именем FileServer (нужно создать вручную). В БД примере уже создано.

Если вы работаете не на ПК сервера то будет включена версия клиента для работы по HTTP иначе версия LOCAL (модуль FilesClientHTTP). Функционал варианта работы LOCAL аналогичен, только работа будет не по сети. Актуально для работы с большими объемами файлов. LOCAL работает независимо от HTTP сервера, данные про подключение ему нужно только для понимания когда запускаться. Для работы LOCAL нужно просто заполнить функции оверрайд или заполнить поля в настройках расширения. Если нет интернета оно все ровно будет локально работать.

Передает файлы стримом в один поток по одному файлу по очереди без какого либо шифрования, подключение по паролю (заполняем функцию SDefAPIKey или поле в настройках расширения), скорость зависит только от скорости вашего интернет соединения. Если операция не удалась вам выдаст сообщение, если включен дебаг то покажет почему именно (дебаг можно отключить в настройках).
В папке с установленным DX в файл ErrorDXF\FilesServerHTTPlog_дата.txt пишет все ошибки, если вы отключили показ debug в настройках расширения то можно посмотреть ошибку в этом файле. Если возникакет ошибка при записи файла проверьте права доступа пользователя к данной папке.
Дополнительная форма 'Описание для файла' хранит в себе картинки для меню и используется при вводе описания файла или изменении имени файла.
При пересылке по HTTP текста он кодируется заменой на дозволенные символы, при получении на сервере раскодируется назад. Итого запрещенных символов в текстах нет.

Клиент FilesClientHTTP (установка на каждую форму + копируем туда запрос)

Файл идентифицирует: установленной в расширении корневой папкой хранения на сервере, именем, названием формы и идентификатором формы recID.

Модуль работает в двух режимах:

А. Работа на сервере LOCAL
Расширение будет запущено если параметры IPlocal, маска сети или шлюз не соответствует серверу или не найден файл-метка.
Работа с файлами проходит локально на ПК, актуально для работы с большими файлами.
По имени файла или описанию нет ограничений по символам (в именах - кроме тех что в принципе не могут быть пропущены Windows).

Б. Работа по HTTP

Расширение будет запущено если параметры IPlocal, маска сети, шлюз соответствует серверу и на ПК существует файл метка. Работа с файлами проходит по протоколу HTTP.
При скачивании файла на клиент он будет сохранен в папке 'Имя пользователя_файлы'\форма\idrec в локальной директории установки DX. Если файл удален после просмотра и папка пуста она будет удалена.

Большинство возможностей аналогичны для HTTP и LOCAL.
Возможности:

1. скачать для просмотра файл из сервера (для скачивания и просмотра - двойной клик по записи в запросе). Для версии работы на сервере просто открывает файл для просмотра.
2. открыть папку с файлами с выделенным целевым файлом. Если удаленная работа и файл еще не скачан будет предложено его скачать.
3. добавить файлы в хранилище сервера создав соответствующую запись в БД (бросая на форму или кнопкой).
4. создавать в БД записи о файлах что были вручную добавлены на сервере (можно выбрать при настройке. Действие происходит при открытии формы из запросом. Если у вас не стабильный интернет лучше отключить иначе будет подтормаживать).
6. добавить описание до 100 символов, нет запрещенных символов (если в настройках расширения выбран чекбокс на форме для активации всплывающего окна описания.
Если при это на форме описания файла поставить галочку 'Применить ко всем файлам' то описание будет добавлено ко всем добавленным за раз файлам).
7. удалить файлы (при этом в настройках расширения можно выбрать удалять файлы безвозвратно или создавать перейменованную версию что не видит (по умолчанию) запрос, но их можно просмотреть нажав в меню запроса 'Отображать удаленные файлы'). Удалить уже помеченные на удаление через ДХ нельзя, для этого добавлен фильтр.
Если на локальном ПК есть уже скачанная версия будет предложено удалить ее после удаления серверной версии.
8. обновить версию файла на сервере (HTTP работа). Если вы скачали себе для работы файл то нажав в меню 'Обновить файл на сервере' он будет перезаписан на сервер.
При этом при настройке расширения можно выбрать создавать перейменованную версию или удалять старую версию файла).
9. изменить описание к файлу.
10. изменить имя файла (до 150 символов, ограничения по символам Windows).
11. просмотреть локально существующие файлы. Если в запросе подсвечивает имя файла желтым значит на данном ПК он существует и он может быть просмотрен).
12. если нужно переместить папку хранилища с файлами просто скопируйте ее куда нужно вручную и пропишите новую директорию корневой папки в функцию SDefBase или в настройки расширения.
Иван
68 Резервное копирование базы Расширение добавляет кнопку резервного копирования базы на панель инструментов. База архивируется при помощи утилиты 7zip, которая автоматически скачивается с сайта http://mydataexpress.ru. Базы архивируются в определенную папку. Имена архивов имеют вид: дата_время_база.7z. Тип действия: действие при запуске.

2.1 (актуальная)
1. Исправлена ошибка копирования шаблонов, если в пути есть символы кириллицы.

2.0
1. Резервное копирование , восстановление и сжатие сетевой базы данных утилитой gbak.
2. Резервное копирование при закрытии базы.
3. Добавление задачи в планировщик заданий.
Backups.7z

1.0
Backups 1.0.zip
admin
69 Скрыть меню Файл и Помощь Простое расширение, скрывающее стандартные пункты меню "Файл" и "Помощь", оставляя видимым только пункт "О программе". Тип действия - при запуске. admin
70 Скрыть тулбар. Простой акшен для скрытия верхнего или нижнего тулбара. Цеплять на форму.

Code: Выделить всё

{@action
Id=A602C679-A37B-4B45-B03C-38664891E217
Target=form
OrigName=StartHideToolbar
Name=Скрыть тулбар.
Group=Интерфейс
UI=
<ui>
 <checkbox  name="HideBeginU" caption="Скрыть верхний тулбар при старте"/>
 <checkbox  name="HideBeginD" caption="Скрыть нижний тулбар при старте"/>
</ui>
Description=Скрывает верхний или нижний тулбары
@}

procedure StartHideToolbar(HideBeginU,HideBeginD:boolean);

begin
if  (HideBeginU = true) then  MainWindow.Toolbar.Visible := not HideBeginU;
if  (HideBeginD = true) then  MainWindow.StatusBar.Visible := not HideBeginD;
end;


Code: Выделить всё

{@action
Id=4BC5175C-FA7C-406B-A325-EE980EF71EC8
Target=main
OrigName=HideToolbar
Name=Скрыть тулбар.
Group=Интерфейс
UI=
<ui>
 <divider caption="Действие не имеет настроек"/>
</ui>
Description=Скрывает верхний тулбар при активной "простой форме".
@}

var OldMainWindow_pages_OnChange: TNotifyEvent;

function GetActiveForm:TDxForm;
begin
  result:=MainWindow.FormViews[MainWindow.Pages.ActivePageIndex].Form;
end;

procedure MainWindow_pages_OnChange(sender: Tobject);
begin
    if OldMainWindow_pages_OnChange<>nil then
    OldMainWindow_pages_OnChange(sender);
    MainWindow.Toolbar.Visible := (GetActiveForm.ViewType <> vtSimpleForm);
end;

procedure HideToolbar;
begin
  OldMainWindow_pages_OnChange:=MainWindow.pages.OnChange;
  MainWindow.pages.OnChange:=@MainWindow_pages_OnChange;
end;
SirWolf
71 Сокращатель ссылок (u.to) Функция: "U_TO". Сокращает длинный URL посредством одноименного сервиса.
Группа: "Интернет"

Пример: U_TO('https://forum.mydataexpress.ru')

Результат: https://u.to/V5gKFg

Примечание:
Сервис не предоставляет открытого API для полноценного с ним взаимодействия, посему функция реализована "альтернативным" способом (то есть - ее стабильная работа не гарантируется).
На каком-то "превышении лимита" начинает себя пиарить просит "немного подождать":
Изображение


[ Скачать ]

Develop-Soft
72 Сохранение ширины и порядка колонок grid формы Каждый user может сам под себя настроить ширину и порядок колонок:
просто меняете ширину и/или позицию колонки, при следующем запуске всё восстанавливается
kok80
73 Сумма прописью на английском Доброго дня!

Возможно, кому-то пригодится...

TotalByWords.zip
Runenkov
74 Телеграм бот для DataExpress ИзображениеТелеграм бот для DataExpress.

Как всегда вопросы, пожелания, предложения и конструктивная критика приветствуются.


Если есть необходимость заставить бота создавать записи в базе, то это можно сделать с помощью функции CreateRec. Поиск и вывод информации из базы удобнее делать с помощью DBMERGEA.

МОДУЛЬ

Эмоциональные посты типа: "О ужас ничего не работает. Всё пропало." - мне не интересны и по факту это просто флуд. Если вам нечего сказать по существу темы - проходите мимо.

Еще раз. Я не против критики, если она по делу. Я против "пугалок" и "страшилок".
jurist23rus
75 Транслитерация кириллицы. Иногда нужна транслитерация, особенно имён-фамилий. Пользуюсь этим расширением.

Расширение возвращает надписи кириллицей на латинице в версии Волапюк, ИКАО (для проездных документов, например загранпаспортов) и на туркменской латинице.

Translit.epas

Демо:
TRANSLIT.zip
Runenkov
76 Убрать нули без потери точности dxCalcEdit Расширение для визуального представления на форме чисел без лишних ноликов без потери точности. Все вычисления
что были прописаны на полях или в скриптах будут срабатывать, изменится только вид полей при открытии формы. Смотрите скрины до и после.

Особенности
На двойной пробел в пустом поле выдаст ноль + запятая для дальнейшего ввода цифры.
Совместим с другими модулями видимости и доступности компонентов.
Можно указать отображать ноль или null независимо от этого свойства в поле dxCalcEdit.
Чексбокс: показать поля правее - ознакомительная функция,
позволяет посмотреть виртуальные TEdit поля и выбранные числовые поля формы порознь.
Иван
77 Управление видимостью/доступностью компонентов Действие формы. Обеспечивает доступность/видимость компонентов по условию.

Актуальная версия
admin
78 Управление закладками форм Действие запуска. Позволяет выполнить кастомные настройки закладок форм и расширить функционал
управления закладками.


(работает с версией DataExpress от 15.03.2020 и новее)

Изображение

Возможности и опции:
Изображение

Управление:
    1. Добавить пункт "Закрыть все" в меню закладок.
    Добавляет в меню закладок дополнительный пункт, нажатием на который можно закрыть все закладки (кроме добавленных в исключения)

    2. Закрытие нажатием колесика мыши
    Активирует возможность закрытия закладки указанным способом (закладки, добавленные в исключения - не закрываются).

    3. Разрешить перетаскивание
    Опция позволяет перетаскивать мышью закладки относительно друг друга.

    4. Запретить закрытие
    Блокирует от закрытия любым способом закладки указанные в списке.

Внешний вид:
    5. Высота закладки в пикселях
    Числовое значение высоты закладок (в пикселях). Установлено ограничение в диапазоне 16..64.

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

    7. Размер шрифта
    Устанавливает размер шрифта (при пустом значении - будет установлен шрифт по-умолчанию).

    8. Стиль шрифта:
    • Жирный
    • Наклонный
    • Подчеркнутый

    9. Иконки закладок/форм:
    Устанавливает выбранные из галереи иконки для закладки и окна формы редактирования (если установлен режим отображения "только таблица).

dxdb_icon Демо | [ Скачать ]

Develop-Soft
79 Форматирование даты и времени Устанавливается как и любой другой модуль расширений. Что это такое и как установить можно прочесть тут. Содержит функции:

FormatDate ('строка форматирования', [Дата]) - преобразует дату в строку с определённым форматированием.
y = Год из 2-х последних цифр
yy = Год из 2-х последних цифр
yyyy = Год из 4-х цифр
m = Номер месяца без 0
mm = Номер месяца как 2 цифры
mmm = Месяц используя ShortDayNames (Янв)
mmmm = Месяц используя LongDayNames (Январь)
d = Число без 0
dd = Число как 2 цифры
ddd = Число используя ShortDayNames (Воск)
dddd = Число используя LongDayNames (Воскресенье)
ddddd = Число в ShortDateFormat
dddddd = Число в LongDateFormat

FormatDate ('dddddd', [Дата]) //Возвращает: 09 Февраля 2000
FormatDate ('dddd d mmmm yyyy', [Дата]) //Возвращает: Среда 9 Февраля 2000
FormatDate ('ddd d mmm yyyy', [Дата]) //Возвращает: Ср 9 Фев 2000


FormatTime ('строка форматирования', [Время]) - преобразует время в строку с определённым форматированием.
h = Час без 0
hh = Час как 2 цифры
n = Минуты без 0
nn = Минуты как 2 цифры
s = Секунды без 0
ss = Секунды как 2 цифры
z = Миллисекунды без 0
zzz = Миллисекунды как 2 цифры
t = Используя ShortTimeFormat
tt = Используя LongTimeFormat

FormatTime ('t', [Время]) //Возвращает: 01:02
FormatTime ('tt', [Время]) //Возвращает: 01:02:03
FormatTime ('hh:mm:ss.zzz', [Время]) //Возвращает: 01:02:03.004
FormatTime ('h:m:s.z', [Время]) //Возвращает: 1:2:3.4
jurist23rus


Еще расширения