1 (edited by Vickus 2025-07-15 06:08:10)

Topic: Присвоение артикула

Добрый день!
Помогите, пожалуйста! Необходимо при добавлении товара в базу присваивать ему автоматически артикул товара, к примеру: У00001, У00002 и т.д. При удалении товара артикул, ранее использованный поторяться на новом товаре не должен. Заранее всех благодарю!

Post's attachments

Attachment icon sample.jpg 197.73 kb, 13 downloads since 2025-07-15 

2 (edited by k245 2025-07-15 07:46:07)

Re: Присвоение артикула

Если шаблон артикула включает только одну последовательность уникальных цифр, то могу порекомендовать реализовать артикул как вычисляемое поле, в состав которого будет входить ID записи. Такое решение подойдет при любом количестве пользователей, выполняющей операции добавления, для любой СУБД.


Пример:

 ('У'|| SUBSTR( 10000+id,2,4) )  

Результат:
https://myvisualdatabase.com/forum/misc.php?action=pun_attachment&item=11119&download=0

Post's attachments

Attachment icon вычисляемое поле.png 9.86 kb, 15 downloads since 2025-07-15 

Визуальное программирование: блог и телеграм-канал.

Re: Присвоение артикула

Могу предположить, что буквы в артикуле отражают какие-либо свойства товара (категории, материалы и т.д.) В этом случае выражение будет немного сложней - возможно потребуется использовать CASE для выбора символов или даже подзапрос, но в любом случае это себя оправдает.


Из минусов данного подхода могу отметить, что артикул может поменяться при изменении алгоритма его вычисления. Если это недопустимо, то тогда создание текста артикула нужно реализовать скриптом, но после добавления записи, то есть в момент, когда уникальное значение ID уже существует. Подходящее место для этого - событие onAfterClick на кнопке сохранения данных формы редактирования. Но в этом случае потенциально могут быть проблемы с уникальностью.

Визуальное программирование: блог и телеграм-канал.

4 (edited by Vickus 2025-07-15 08:08:15)

Re: Присвоение артикула

k245 wrote:

Если шаблон артикула включает только одну последовательность уникальных цифр, то могу порекомендовать реализовать артикул как вычисляемое поле, в состав которого будет входить ID записи. Такое решение подойдет при любом количестве пользователей, выполняющей операции добавления, для любой СУБД.


Пример:

 ('У'|| SUBSTR( 10000+id,2,4) )  

Результат:
https://myvisualdatabase.com/forum/misc.php?action=pun_attachment&item=11119&download=0


Огромное спасибо за ПОМОЩЬ!
не получается. Сможете посмотреть в чем ошибка? И не могу сделать, чтобы сумма автоматичски считалась (количество * цену)

P.S. Исправил в вычислительном поле id на main.id и заработало. Помогите, пожалуйста с автоподсчетом суммы. Спасибо

Post's attachments

Attachment icon vickus.rar 293.92 kb, 50 downloads since 2025-07-15 

5 (edited by k245 2025-07-15 08:25:38)

Re: Присвоение артикула

Для суммы лучше сделать вычисляемое поле:

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

Post's attachments

Attachment icon total.png 19.21 kb, 13 downloads since 2025-07-15 

Визуальное программирование: блог и телеграм-канал.

6 (edited by k245 2025-07-15 08:29:32)

Re: Присвоение артикула

Чтобы поле отображалось как деньги, лучше использовать скрипт.

procedure FrmMain_table_main_OnChange (Sender: TObject);
begin
  Grid_FinFormat(Sender,6)
end;

procedure Grid_FinFormat(Sender: TObject; AColNumber: integer; ASum: boolean = True);
// форматирование колонки таблицы/дерева в денежный формат
var
  tmpGrid: TdbStringGridEx;
begin
  tmpGrid := TdbStringGridEx(Sender);
  TNxNumberColumn(tmpGrid.Columns[AColNumber]).FormatMask := '#,##0.00';
  if ASum then
  begin
    // tmpGrid.Options := TdbStringGridEx(AGrid).Options + goFooter;
    TNxNumberColumn(tmpGrid.Columns[AColNumber]).Footer.FormatMask := '#,##0.00';
    TNxNumberColumn(tmpGrid.Columns[AColNumber]).Footer.FormulaKind := fkSum;
  end;
end;

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

P.S. Можно форматирование добавить в сам SQL-запрос, но работать будет криво, так как региональные настройки всё будут портить...

Post's attachments

Attachment icon img-2025-07-15-11-28-44.png 11.92 kb, 14 downloads since 2025-07-15 

Визуальное программирование: блог и телеграм-канал.

Re: Присвоение артикула

k245 wrote:

Могу предположить, что буквы в артикуле отражают какие-либо свойства товара (категории, материалы и т.д.) В этом случае выражение будет немного сложней - возможно потребуется использовать CASE для выбора символов или даже подзапрос, но в любом случае это себя оправдает.


Из минусов данного подхода могу отметить, что артикул может поменяться при изменении алгоритма его вычисления. Если это недопустимо, то тогда создание текста артикула нужно реализовать скриптом, но после добавления записи, то есть в момент, когда уникальное значение ID уже существует. Подходящее место для этого - событие onAfterClick на кнопке сохранения данных формы редактирования. Но в этом случае потенциально могут быть проблемы с уникальностью.

********************************

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

CASE
WHEN main.id_category = 1 THEN ('O'|| SUBSTR(1000000 + main.id,2,6) )
WHEN main.id_category = 2 THEN ('G'|| SUBSTR(1000000 + main.id,2,6) )
WHEN main.id_category = 3 THEN ('A'|| SUBSTR(1000000 + main.id,2,6) )
ELSE '' END

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

Re: Присвоение артикула

Привет, Викус!
Если я правильно понял твой вопрос, то можно попробовать что-то вроде этого (с этим решением тебе не придётся «жёстко прописывать» категории, так что можно просто добавить новые, и счётчик автоматически начнёт отсчёт с 10 000 для каждой новой категории).
С уважением,
Derek.
.
If I understand your question correctly, you can try something like this (with this solution you don't have to "hardcode" the categories, so you can just add new ones and the counter will automatically start counting from 10,000 for each new category).

Post's attachments

Attachment icon wickus1.zip 340.73 kb, 48 downloads since 2025-07-18 

Re: Присвоение артикула

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

Визуальное программирование: блог и телеграм-канал.

Re: Присвоение артикула

For SQLite

procedure Frm_add_ComboBox1_OnChange (Sender: TObject);
begin
  frm_add.edit1.text := copy(frm_add.ComboBox1.text,1,1);
end;

procedure calculate (Sender: TObject);
begin
  frm_add.summa_tovara.value := frm_add.price_tovar.value * frm_add.kolvo_tovara.value;
end;

procedure Frm_add_OnShow (Sender: TObject; Action: string);
begin
  frm_add.caption := 'товар:  ' + frm_add.article_tovar.text;
end;

begin
    FrmMain.menu := nil;
    FrmMain.WindowState := wsMaximized;

  SQLExecute('CREATE TRIGGER IF NOT EXISTS "tr_ins" AFTER INSERT ON "main" FOR EACH ROW '+
    'BEGIN UPDATE main SET tovar = (SELECT CASE WHEN IFNULL(tovar,0) < 10000 THEN 10000 ELSE MAX(tovar)+1 END FROM main WHERE prefix=new.prefix), '+
    'article_tovar = (SELECT prefix||(SELECT CASE WHEN IFNULL(tovar,0) < 10000 THEN 10000 ELSE MAX(tovar)+1 END FROM main WHERE prefix=new.prefix) '+
    'FROM main WHERE prefix=new.prefix) WHERE id=new.id; END;');
end.

Re: Присвоение артикула

derek wrote:

Привет, Викус!
Если я правильно понял твой вопрос, то можно попробовать что-то вроде этого (с этим решением тебе не придётся «жёстко прописывать» категории, так что можно просто добавить новые, и счётчик автоматически начнёт отсчёт с 10 000 для каждой новой категории).
С уважением,
Derek.
.
If I understand your question correctly, you can try something like this (with this solution you don't have to "hardcode" the categories, so you can just add new ones and the counter will automatically start counting from 10,000 for each new category).

Огромное спасибо ДЕРЕК!
Ваш приер подошел отлично. Можете помочь еще с таким вопросом. Артикул формируется из первого символа названия категории товара. Если категории товаров начинаются с одинаковой буквы, то артикул будет неверным (например: Одежда и Очки) Можно выводить две или три первые буквы заглавными в качестве артикуда? Спасибо!

Re: Присвоение артикула

Привет Vickus!
Просто измените строку 3 в скрипте.
В приложенном примере теперь используется значение из Frm_add.combobox1.text, и, начиная с позиции 1, первые два символа, за которыми следует знак «-» (но, конечно, вы можете использовать любое количество символов и изменить формат по своему усмотрению).
Я также изменил скрипт так, чтобы это происходило при сохранении записи, а не при выборе значения из выпадающего списка «Категория» (это сделано для того, чтобы уменьшить вероятность одновременных операций (если у вас несколько пользователей), как упоминал K245).
Надеюсь, это поможет.
Derek.

Post's attachments

Attachment icon wickus2.zip 340.81 kb, 46 downloads since 2025-07-19 

Re: Присвоение артикула

sparrow wrote:

For SQLite

procedure Frm_add_ComboBox1_OnChange (Sender: TObject);
begin
  frm_add.edit1.text := copy(frm_add.ComboBox1.text,1,1);
end;

procedure calculate (Sender: TObject);
begin
  frm_add.summa_tovara.value := frm_add.price_tovar.value * frm_add.kolvo_tovara.value;
end;

procedure Frm_add_OnShow (Sender: TObject; Action: string);
begin
  frm_add.caption := 'товар:  ' + frm_add.article_tovar.text;
end;

begin
    FrmMain.menu := nil;
    FrmMain.WindowState := wsMaximized;

  SQLExecute('CREATE TRIGGER IF NOT EXISTS "tr_ins" AFTER INSERT ON "main" FOR EACH ROW '+
    'BEGIN UPDATE main SET tovar = (SELECT CASE WHEN IFNULL(tovar,0) < 10000 THEN 10000 ELSE MAX(tovar)+1 END FROM main WHERE prefix=new.prefix), '+
    'article_tovar = (SELECT prefix||(SELECT CASE WHEN IFNULL(tovar,0) < 10000 THEN 10000 ELSE MAX(tovar)+1 END FROM main WHERE prefix=new.prefix) '+
    'FROM main WHERE prefix=new.prefix) WHERE id=new.id; END;');
end.

Триггер - самое лучшее универсальное решение. Жаль, что MVDB нет встроенной поддержки триггеров.

Визуальное программирование: блог и телеграм-канал.

14 (edited by Vickus 2025-07-22 05:50:03)

Re: Присвоение артикула

derek wrote:

Привет Vickus!
Просто измените строку 3 в скрипте.
В приложенном примере теперь используется значение из Frm_add.combobox1.text, и, начиная с позиции 1, первые два символа, за которыми следует знак «-» (но, конечно, вы можете использовать любое количество символов и изменить формат по своему усмотрению).
Я также изменил скрипт так, чтобы это происходило при сохранении записи, а не при выборе значения из выпадающего списка «Категория» (это сделано для того, чтобы уменьшить вероятность одновременных операций (если у вас несколько пользователей), как упоминал K245).
Надеюсь, это поможет.
Derek.

Дерек, а возможно ли сделать так, чтобы Артикул формировался не из первых символов категории (например: ОДЕЖДА - ОД00001, введнной при заведении категории аббревиатурой на свое усмотрение (например: категория: ОДЕЖДА > аббревиатура: CL; категория: ОЧКИ > аббревиатура: GL В конечном итоге при выборе категории ОДЕЖДА на форме заведения товара, в основной таблице бы выводился код CL00001.
Заранее БЛАГОДАРЮ за уже оказанную помощь и за помощь в решении данного вопроса!

Re: Присвоение артикула

Привет Vickus!
Попробуйте что-то вроде этого (см. приложение).
Это полностью основано на данных (это всегда мой личный выбор), и все варианты хранятся в таблице «Категории».
В таблице «Категории» добавьте «префикс» (он может быть любым) и «начальный номер» (он может быть одинаковым для всех категорий или можно задать отдельные «начальные номера» для каждой категории).
Новые категории можно добавлять в любое время, а существующие префиксы можно изменять.
Думаю, это даст вам максимальную гибкость.
С уважением,
Derek.

Post's attachments

Attachment icon wickus3.zip 340.14 kb, 47 downloads since 2025-07-22 

Re: Присвоение артикула

derek wrote:

Привет Vickus!
Попробуйте что-то вроде этого (см. приложение).
Это полностью основано на данных (это всегда мой личный выбор), и все варианты хранятся в таблице «Категории».
В таблице «Категории» добавьте «префикс» (он может быть любым) и «начальный номер» (он может быть одинаковым для всех категорий или можно задать отдельные «начальные номера» для каждой категории).
Новые категории можно добавлять в любое время, а существующие префиксы можно изменять.
Думаю, это даст вам максимальную гибкость.
С уважением,
Derek.


Дерек, ОГРОМНОЕ ВАМ СПАСИБО!
Все получилось!

Re: Присвоение артикула

derek wrote:

Привет Vickus!
Попробуйте что-то вроде этого (см. приложение).
Это полностью основано на данных (это всегда мой личный выбор), и все варианты хранятся в таблице «Категории».
В таблице «Категории» добавьте «префикс» (он может быть любым) и «начальный номер» (он может быть одинаковым для всех категорий или можно задать отдельные «начальные номера» для каждой категории).
Новые категории можно добавлять в любое время, а существующие префиксы можно изменять.
Думаю, это даст вам максимальную гибкость.
С уважением,
Derek.


Дерек, снова прошу у Вас помощи.
Хочу сделать доступ к базе через Интернет и чтобы можно было загружать в базу данные из файла Excel.
Можете помочь с данными вопросами (импорт через скрипт (кнопка "Импорт") и нужно ли что-то менять в скриптах для работы в сетевой версии)?
Снова заранее БЛАГОДАРЮ!

P.S. Смог подключить базу к MySQL и перенести данные через PHPMyAdmin, но артикул перестал формироваться. Я так понимаю. что что-то в вычисляемом поле?

Post's attachments

Attachment icon 1.pdf 77.91 kb, 41 downloads since 2025-07-25 

Re: Присвоение артикула

В MySQL для объединения строк вместо вертикальных палок нужно использовать функцию CONCAT:
SQLite -  'Hello' || ' world'
MySQL - CONCAT('Hello', ' world')

P.S. Доступ к базе через интернет сами будете делать? Вы хотя бы примерно представляете сложность этой задачи? Увы, генератор Web-форм, который есть в My Visual Database, служит скорей для иллюстрации такой возможности, не предоставляя конечного решения.

Визуальное программирование: блог и телеграм-канал.

19 (edited by Vickus 2025-07-25 16:30:18)

Re: Присвоение артикула

k245 wrote:

В MySQL для объединения строк вместо вертикальных палок нужно использовать функцию CONCAT:
SQLite -  'Hello' || ' world'
MySQL - CONCAT('Hello', ' world')

P.S. Доступ к базе через интернет сами будете делать? Вы хотя бы примерно представляете сложность этой задачи? Увы, генератор Web-форм, который есть в My Visual Database, служит скорей для иллюстрации такой возможности, не предоставляя конечного решения.

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

(select prefix from categories where id = id_categories)||article_tovar 

Можете подсказать как должно быть с конкатизацией? Спасибо

P.S. Вроде так заработало:

(SELECT concat(categories.prefix, main.article_tovar) FROM categories WHERE id = id_categories)