Последняя версия DataExpress 26.9.23

Изображение Скачать | Изображение Что нового? | Демо

kok80-поиск ссылок

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

Модератор: Разработчики расширений

kok80
Эксперт
Сообщения: 618
Зарегистрирован: 02 июл 2018, 21:45
Благодарил (а): 23 раза
Поблагодарили: 156 раз

kok80-поиск ссылок

Сообщение kok80 » 25 май 2021, 13:48

Поиск ссылок на форму по всем объектам базы из контекстного меню grid формы и запроса.
Поддерживает рекурсию (поиск ссылок в найденных формах).
возможность выбора нескольких значений для поиска ссылок
замена во всех найденных ссылках значений на другое
добавлена поддержка расширений kok80-ExportToExcel (выгрузка найденных ссылок в xls) и kok80-poisk (при выборе значения для замены)

Пароль в примере - 1
Вложения
Screenshot_1.jpg
Screenshot_1.jpg (186.81 КБ) 1884 просмотра
пример.zip
(333.89 КБ) 48 скачиваний
kok80-Поиск ссылок3.0.zip
(20.44 КБ) 54 скачивания

Теги:

kok80
Эксперт
Сообщения: 618
Зарегистрирован: 02 июл 2018, 21:45
Благодарил (а): 23 раза
Поблагодарили: 156 раз

kok80-поиск ссылок

Сообщение kok80 » 01 сен 2026, 00:40

все равно пришлите с ошибкой базу, как сможете.

Pozharskiy1991
Интересующийся
Сообщения: 110
Зарегистрирован: 31 май 2024, 15:07
Откуда: МО, Пушкино
Благодарил (а): 42 раза
Поблагодарили: 26 раз

kok80-поиск ссылок

Сообщение Pozharskiy1991 » 01 сен 2026, 09:23

Извиняюсь, какая-то мистика, сегодня не получилось добиться той же ошибки. Теперь все работает нормально :D

Pozharskiy1991
Интересующийся
Сообщения: 110
Зарегистрирован: 31 май 2024, 15:07
Откуда: МО, Пушкино
Благодарил (а): 42 раза
Поблагодарили: 26 раз

kok80-поиск ссылок

Сообщение Pozharskiy1991 » 16 сен 2026, 09:26

При нажатии кнопки "замене всех значений" открывается окно списка, но в нем не отображается дерево и не работает поиск. Это не очень удобно, есть возможность исправить исправить это?
Вложения
Поиск ссылок.png
Поиск ссылок.png (69.71 КБ) 452 просмотра

Аватара пользователя
admin
Разработчик
Сообщения: 8036
Зарегистрирован: 14 мар 2016, 11:32
Откуда: Ленинградская
Благодарил (а): 291 раз
Поблагодарили: 1913 раз

kok80-поиск ссылок

Сообщение admin » 16 сен 2026, 21:11

У вас какое-то нестандартное окно списка. Правой кнопкой дерево не обновляется? Еще в настройках связи объекта есть опция обновлять дерево при каждом показе окна списка.

Pozharskiy1991 писал(а):Странно, почему то дома не удалось повторить этой ошибки на тестовой базе. Но нашел решение, поместил в "действиях при загрузки" действие "Поиск ссылок" первым, пока ошибки больше не выскакивает в рабочей базе.

Скорее всего, в расширении kok80 не все старые обработчики запоминаются и вызываются.

Pozharskiy1991
Интересующийся
Сообщения: 110
Зарегистрирован: 31 май 2024, 15:07
Откуда: МО, Пушкино
Благодарил (а): 42 раза
Поблагодарили: 26 раз

kok80-поиск ссылок

Сообщение Pozharskiy1991 » 17 сен 2026, 09:18

Да, дерево обновилось. Но поиск не работает.

Pozharskiy1991
Интересующийся
Сообщения: 110
Зарегистрирован: 31 май 2024, 15:07
Откуда: МО, Пушкино
Благодарил (а): 42 раза
Поблагодарили: 26 раз

kok80-поиск ссылок

Сообщение Pozharskiy1991 » 17 сен 2026, 09:33

Поиск не работал из за моего скрипта на форме, но вот дерево автоматически не обновляется.
Скрипт пользователя

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

// ═══════════════════════════════════════════════════════════
// МОДУЛЬ ТЕМЫ ОФОРМЛЕНИЯ (ThemeModule)
// ═══════════════════════════════════════════════════════════
// Версия: 1.0
// Дата: 22.08.2026
//
// Описание:
//   Модуль для применения цветовых тем к формам.
//   Поддерживает темы: "Темная", "Светлая", "По умолчанию".
//   Тема пользователя хранится в форме "Настройки пользователя".
//
// Подключение:
//   {$I ThemeModule}
//
// Использование:
//   Модуль автоматически применяет тему при открытии формы.
//   Для ручного переключения: SwitchTheme('Темная');
//
// Примечание:
//   Обработчики OnPrepareCanvas и OnDrawColumnCell НЕ трогаем,
//   так как они отвечают за раскраску строк по условиям формы.
// ═══════════════════════════════════════════════════════════

// ───────────────────────────────────────────────────────────
// КОНСТАНТЫ
// ───────────────────────────────────────────────────────────
const
  // Размеры шрифтов
  FONT_SIZE_HEADER = 11;     // Размер шрифта заголовков таблицы
  TREE_FONT_SIZE = 11;       // Размер шрифта дерева

  // Высота строк
  ROW_HEIGHT = 24;           // Высота строк данных в таблице

  // Особый столбец
  CUSTOM_COLUMN_NAME = 'СК'; // Столбец со скрепкой (требует особой настройки)

// ───────────────────────────────────────────────────────────
// ТИПЫ ДАННЫХ
// ───────────────────────────────────────────────────────────
type
  TSettingsTheme = record
    // ── Цвета таблицы ──
    FormBackgroundColor: TColor;        // Цвет фона формы
    GridBackgroundColor: TColor;        // Цвет фона таблицы
    CellTextColor: TColor;              // Цвет текста ячеек
    HeaderTextColor: TColor;            // Цвет текста заголовков
    GridLineColor: TColor;              // Цвет линий сетки
    HeaderBackgroundColor: TColor;      // Цвет фона заголовков
    AlternateRowColor: TColor;          // Цвет четных строк
    SelectedCellColor: TColor;          // Цвет фона выделенной ячейки
    SelectedTextColor: TColor;          // Цвет текста выделенной ячейки
    BorderColor: TColor;                // Цвет рамки таблицы
    HighlightRowColor: TColor;          // Цвет подсветки строки
    InactiveSelectedColor: TColor;      // Цвет фона неактивного выделения
    InactiveSelectedTextColor: TColor;  // Цвет текста неактивного выделения

    // ── Настройки таблицы ──
    IsFlatStyle: Boolean;               // Плоский стиль таблицы
    GridLineStyle: TPenStyle;           // Стиль линий сетки

    // ── Цвета дерева ──
    TreeBackgroundColor: TColor;        // Цвет фона дерева
    TreeTextColor: TColor;              // Цвет шрифта дерева
    TreeSelectedColor: TColor;          // Цвет выделенного узла дерева
    TreeSelectedTextColor: TColor;      // Цвет шрифта выделенного узла
    TreeFontStyle: TFontStyles;         // Стиль шрифта дерева

    // ── Название темы ──
    ThemeName: String;                  // Название текущей темы
  end;

// ───────────────────────────────────────────────────────────
// ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
// ───────────────────────────────────────────────────────────
var
  Theme: TSettingsTheme;         // Текущая тема оформления
  IsDefaultTheme: Boolean;       // Флаг: используется ли тема по умолчанию

// ───────────────────────────────────────────────────────────
// ФУНКЦИИ
// ───────────────────────────────────────────────────────────

// Получение названия темы текущего пользователя
function GetUserTheme: String;
var
  Fm: TdxForm;
  UserID: Variant;
begin
  Result := 'По умолчанию';  // По умолчанию, если тема не найдена

  // Получаем ID текущего пользователя
  UserID := EvalExpr('GETVAR(''ID_USER'')', Self);
  if VarIsNull(UserID) or VarIsEmpty(UserID) then
    Exit;

  // Открываем форму настроек
  Fm := TdxForm.Create('Настройки пользователя');
  try
    Fm.Open;
    Fm.OpenRecords('[Пользователь] = ' + VarToStr(UserID), nil, False);

    if Fm.RecordCount > 0 then
    begin
      Fm.MoveFirst;
      Result := Fm.AsS['Тема форм'];

      // Если тема пустая — используем по умолчанию
      if Result = '' then
        Result := 'По умолчанию';
    end;
  finally
    Fm.Free;
  end;
end;

// Безопасный поиск столбца по имени поля (не вызывает исключение)
function FindColumnSafe(Grid: TdxGrid; FieldName: String): TColumn;
var
  i: Integer;
begin
  Result := nil;

  if Grid = nil then
    Exit;

  for i := 0 to Grid.Columns.Count - 1 do
  begin
    if Grid.Columns[i].Field <> nil then
    begin
      if Grid.Columns[i].Field.FieldName = FieldName then
      begin
        Result := Grid.Columns[i];
        Exit;
      end;
    end;
  end;
end;

// ───────────────────────────────────────────────────────────
// ЗАПОЛНЕНИЕ ТЕМ
// ───────────────────────────────────────────────────────────

// Заполнение темной темы
procedure FillDarkTheme;
begin
  Theme.ThemeName := 'Темная';

  // Цвета таблицы
  Theme.FormBackgroundColor := RGBToColor(40, 40, 40);
  Theme.GridBackgroundColor := RGBToColor(40, 40, 40);
  Theme.CellTextColor := RGBToColor(212, 190, 152);
  Theme.HeaderTextColor := RGBToColor(234, 105, 98);
  Theme.GridLineColor := RGBToColor(100, 100, 100);
  Theme.HeaderBackgroundColor := RGBToColor(60, 60, 60);
  Theme.AlternateRowColor := RGBToColor(40, 40, 40);
  Theme.SelectedCellColor := RGBToColor(70, 70, 70);
  Theme.SelectedTextColor := RGBToColor(231, 138, 78);
  Theme.BorderColor := RGBToColor(90, 83, 80);
  Theme.HighlightRowColor := RGBToColor(65, 65, 65);
  Theme.InactiveSelectedColor := RGBToColor(55, 55, 55);
  Theme.InactiveSelectedTextColor := RGBToColor(200, 200, 200);

  // Настройки таблицы
  Theme.IsFlatStyle := true;
  Theme.GridLineStyle := psDash;

  // Цвета дерева
  Theme.TreeBackgroundColor := RGBToColor(179, 179, 179);
  Theme.TreeTextColor := RGBToColor(85, 85, 85);
  Theme.TreeSelectedColor := RGBToColor(62, 62, 62);
  Theme.TreeSelectedTextColor := RGBToColor(255, 255, 255);
  Theme.TreeFontStyle := [fsBold];
end;

// Заполнение светлой темы
procedure FillLightTheme;
begin
  Theme.ThemeName := 'Светлая';

  // Цвета таблицы
  Theme.FormBackgroundColor := RGBToColor(236, 249, 230);
  Theme.GridBackgroundColor := RGBToColor(236, 249, 230);
  Theme.CellTextColor := RGBToColor(0, 0, 0);
  Theme.HeaderTextColor := RGBToColor(0, 0, 0);
  Theme.GridLineColor := RGBToColor(83, 170, 40);
  Theme.HeaderBackgroundColor := RGBToColor(128, 213, 77);
  Theme.AlternateRowColor := RGBToColor(236, 249, 230);
  Theme.SelectedCellColor := RGBToColor(180, 220, 150);
  Theme.SelectedTextColor := RGBToColor(0, 0, 0);
  Theme.BorderColor := RGBToColor(83, 170, 40);
  Theme.HighlightRowColor := RGBToColor(200, 230, 180);
  Theme.InactiveSelectedColor := RGBToColor(210, 235, 195);
  Theme.InactiveSelectedTextColor := RGBToColor(50, 50, 50);

  // Настройки таблицы
  Theme.IsFlatStyle := false;
  Theme.GridLineStyle := psInsideFrame;

  // Цвета дерева
  Theme.TreeBackgroundColor := RGBToColor(255, 255, 255);
  Theme.TreeTextColor := RGBToColor(0, 0, 0);
  Theme.TreeSelectedColor := RGBToColor(180, 220, 150);
  Theme.TreeSelectedTextColor := RGBToColor(0, 0, 0);
  Theme.TreeFontStyle := [];
end;

// Заполнение темы по умолчанию
procedure FillDefaultTheme;
begin
  IsDefaultTheme := True;
  Theme.ThemeName := 'По умолчанию';
end;

// Выбор и заполнение темы по названию
procedure FillTheme(UserTheme: String);
begin
  IsDefaultTheme := False;

  if UserTheme = 'Темная' then
    FillDarkTheme
  else if UserTheme = 'Светлая' then
    FillLightTheme
  else
    FillDefaultTheme;
end;

// ───────────────────────────────────────────────────────────
// ПРИМЕНЕНИЕ ТЕМЫ К ТАБЛИЦЕ
// ───────────────────────────────────────────────────────────

procedure ApplyGridTheme(Grid: TdxGrid);
var
  CustomColumn: TColumn;
begin
  if Grid = nil then
    Exit;

  // ── Основные цвета ──
  Grid.Color := Theme.GridBackgroundColor;
  Grid.Font.Color := Theme.CellTextColor;
  Grid.GridLineColor := Theme.GridLineColor;
  Grid.FixedColor := Theme.HeaderBackgroundColor;
  Grid.AlternateColor := Theme.AlternateRowColor;
  Grid.SelectedColor := Theme.SelectedCellColor;
  Grid.SelectedTextColor := Theme.SelectedTextColor;
  Grid.InactiveSelectedColor := Theme.InactiveSelectedColor;
  Grid.InactiveSelectedTextColor := Theme.InactiveSelectedTextColor;
  Grid.BorderColor := Theme.BorderColor;

  // ── Стиль таблицы ──
  Grid.Flat := Theme.IsFlatStyle;
  Grid.GridLineStyle := Theme.GridLineStyle;
  Grid.DefaultRowHeight := ROW_HEIGHT;

  // ── Заголовки ──
  Grid.TitleFont.Color := Theme.HeaderTextColor;
  Grid.TitleFont.Size := FONT_SIZE_HEADER;
  Grid.TitleFont.Style := [fsBold];

  // ── Столбец со скрепкой ──
  // Примечание: символ скрепки не наследует цвет автоматически,
  // поэтому устанавливаем его явно через свойство колонки.
  CustomColumn := FindColumnSafe(Grid, CUSTOM_COLUMN_NAME);
  if CustomColumn <> nil then
  begin
    CustomColumn.Font.Color := Theme.CellTextColor;
  end;

  // ВАЖНО: НЕ трогаем OnPrepareCanvas и OnDrawColumnCell!
  // Эти обработчики уже настроены в форме и отвечают
  // за раскраску строк по условиям. Если мы их переопределим
  // или отключим (установим в nil), раскраска перестанет работать.
end;

// ───────────────────────────────────────────────────────────
// ПРИМЕНЕНИЕ ТЕМЫ К ДЕРЕВУ
// ───────────────────────────────────────────────────────────

procedure ApplyTreeTheme(Tree: TdxFormTree);
begin
  if Tree = nil then
    Exit;

  Tree.Color := Theme.TreeBackgroundColor;
  Tree.Font.Color := Theme.TreeTextColor;
  Tree.Font.Size := TREE_FONT_SIZE;
  Tree.Font.Style := Theme.TreeFontStyle;
  Tree.SelectionColor := Theme.TreeSelectedColor;
end;

// ───────────────────────────────────────────────────────────
// ПРИМЕНЕНИЕ ТЕМЫ К ФОРМЕ
// ───────────────────────────────────────────────────────────

procedure ApplyThemeToForm(Fm: TdxForm);
begin
  // Если тема по умолчанию — ничего не применяем
  if IsDefaultTheme then
    Exit;

  // Применяем к таблице
  if Fm.Grid <> nil then
  begin
    ApplyGridTheme(Fm.Grid);
    Fm.Grid.Refresh;
  end;

  // Применяем к дереву
  if Fm.Tree <> nil then
  begin
    ApplyTreeTheme(Fm.Tree);
  end;
end;

// ───────────────────────────────────────────────────────────
// ИНИЦИАЛИЗАЦИЯ ТЕМЫ
// ───────────────────────────────────────────────────────────

procedure InitTheme(Fm: TdxForm);
var
  UserTheme: String;
begin
  UserTheme := GetUserTheme;
  FillTheme(UserTheme);
  ApplyThemeToForm(Fm);
end;

// Ручное переключение темы
{procedure SwitchTheme(ThemeName: String);
begin
  FillTheme(ThemeName);
  ApplyThemeToForm(Self);
end;}

// ───────────────────────────────────────────────────────────
// ОБРАБОТЧИКИ СОБЫТИЙ ФОРМЫ
// ───────────────────────────────────────────────────────────

procedure ApplyTheme(Sender: TObject);
begin
  InitTheme(Self);
end;


Скрипт формы

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

{$I ThemeModule}

procedure IconFile (Sender: TObject);
begin
  if Self.Queries['Файлы'].RecordCount > 0 then
    Self['СК'] := 'СК'
  else
    Self['СК'] := null;
end;

//Заполнить при изменении поля
procedure MyFildChange(Sender, Control: TObject; const FieldName: String);
var
  Num_rec : integer;
begin
  if (FieldName = 'Децимальный номер') or (FieldName = 'Вид документа') then
  begin
    Num_rec := EvalExpr('DBCOUNT("Реестр документов архива", "[!Децимальный номер]=[Децимальный номер] & [!Вид документа]=[Вид документа]")', Self);
    Self['Версия файла'] := 'v0.'+ IntToStr(Num_rec + 1);
  end;
  if (FieldName='Версия файла') then
  begin
    Self['Полное обозначение документа с версией']:= EvalExpr('CONCAT([Децимальный номер|Обозначение],CONCAT([Вид документа|Код документа])," ",[Децимальный номер|Наименование],"_",[Версия файла])', Self);
  end;
end;

// Значения по умолчанию при добавлении новой записи
procedure AfterInsert(Sender: TObject);
begin
  Self['Загрузил'] := EvalExpr('GETVAR("ID_USER")', Self);
  Self['Проверил'] := EvalExpr('GETVAR("ID_USER")', Self);
  Self['Разработал'] := EvalExpr('GETVAR("ID_USER")', Self);
  //Self['Инвентарный номер'] := EvalExpr('ZEROS(DBCOUNT("Реестр документов архива", ""),6)', Self);
  Self['Дата загрузки'] := EvalExpr('DATE', Self);
end;


procedure Form_Create;
begin
  Self.OnAfterOpen := @ApplyTheme; //Применить тему из Модуля пользователя {$I ThemeModule}
  Self.OnAfterInsert := @AfterInsert;
  Self.OnFieldChange := @MyFildChange;

  // Используем OnAfterOpen вместо OnAfterClose
  Self.Queries['Файлы'].OnAfterOpen := @IconFile;
  // Или OnAfterScroll
  Self.Queries['Файлы'].OnAfterScroll := @IconFile;
end;
 


Вернуться в «Каталог расширений»