powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Подсчет продуктов рецептуры
20 сообщений из 20, страница 1 из 1
Подсчет продуктов рецептуры
    #32727479
Фотография Geo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть задачка:

Существует, скажем, меню на день:
Блюдо КоличествоСуп 10Рис 10
Есть таблица рецепт ов:
Код блюда Код товара Количество (закладка)Суп Бульон 1Суп Мясо 0.01Бульон Вода 1Бульон Мясо 0.01Рис Крупа рисовая 1
Т.е. каждый товар рецепта в свою очередь тоже может являться рецептом.

Надо сосчитать количество продуктов на меню:
Продукт КоличествоВода 10Мясо 0.2Крупа рисовая 10
Вижу два решения, рекурсия или временная таблица, но встает вопрос по реализации в mdb.

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

Временная таблица, которую можно заполнить в цикле всеми рецептами меню, включая вложенные, а потом одним запросом (утрирую, конечно, ведь есть еще и FIFO/LIFO, но в данном случае это не важно) посчитать кол-во товаров. Но ее тоже надо заполнить... О! А заполнить ее можно в цикле запросом! Т.е. первым запросом кладем в нее рецепты первого уровня, а потом в цикле запросом отбираем из нее рецепты одного уровня и добавляем в нее же рецепты следующего, пока таковые имеются. А потом последним запросом считается сразу весь расход продуктов.

Никто не решал такую задачу? М.б. есть красивше способы?
...
Рейтинг: 0 / 0
Подсчет продуктов рецептуры
    #32727508
Iskander68
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А есть ли необходимость объединять в одну таблицу ингридиенты ("товары" -
суп) и "подингридиенты" (вода)? Может стоит рассмотреть создание новой
таблицы, где бульон будет расписан на "атомарные" ингридиенты - вода, мясо и
т.д.?

--
Regards
Alexander Artamonov


"Geo" <nospam@sql.ru>; сообщил/сообщила в новостях следующее:
news:1015201@sql.ru...
Есть задачка:

Существует, скажем, меню на день:
БлюдоКоличество
Суп10
Рис10


Есть таблица рецептов:
Код блюдаКод товараКоличество (закладка)
СупБульон1
СупМясо0.01
БульонВода1
БульонМясо0.01
РисКрупа рисовая1


Т.е. каждый товар рецепта в свою очередь тоже может являться рецептом.

Вижу два решения, рекурсия или временная таблица, но встает вопрос по
реализации в mdb.

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

Временная таблица, которую можно заполнить в цикле всеми рецептами меню,
включая вложенные, а потом одним запросом (утрирую, конечно, ведь есть еще и
FIFO/LIFO, но в данном случае это не важно) посчитать кол-во товаров. Но ее
тоже надо заполнить... О! А заполнить ее можно в цикле запросом! Т.е. первым
запросом кладем в нее рецепты первого уровня, а потом в цикле запросом
отбираем из нее рецепты одного уровня и добавляем в нее же рецепты
следующего, пока таковые имеются. А потом последним запросом считается сразу
весь расход продуктов.

Никто не решал такую задачу? М.б. есть красивше способы?
Тема Ответить

Posted via ActualForum NNTP Server 1.0
...
Рейтинг: 0 / 0
Подсчет продуктов рецептуры
    #32727529
Фотография Geo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А собственно требуемое и забыл написать :(
Ну это я поправил.

2 Iskander
авторА есть ли необходимость объединять в одну таблицу ингридиенты ("товары" - суп) и "подингридиенты" (вода)? Может стоит рассмотреть создание новой таблицы, где бульон будет расписан на "атомарные" ингридиенты - вода, мясо и
т.д.?
Конечно. Такая таблица есть - называется "рецепты". В ней бульон расписан на воду и мясо. А вот суп на воду и мясо расписать не получится - в него помимо прочего входит именно "бульон", а не составляющие последнего.
...
Рейтинг: 0 / 0
Подсчет продуктов рецептуры
    #32727724
Iskander68
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну у меня вот что получилось. Пять таблиц. См. скриншот. Бульон есть и в блюдах (Meals) и в Ингридиентах (Ingredients). Бульон как блюдо состоит из бульона как ингридиента, а тот в свою очередь из атомов (вода, мясо). Вода и мясо есть и в ингридиентах, и в атомах. Не знаю, правда, чем это лучше рекурсии :-)
...
Рейтинг: 0 / 0
Подсчет продуктов рецептуры
    #32727736
Фотография paparome
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прикольная задачка - мне понравилась :)

Я тут базеху накрапал - для примера одной из реализаций :)
Структуру я немножко переделал - но это мелочи :)

Прилагаю файл

Описание
Там VBA кода нет - только таблы и запросы
Запросы заполняют таблицу "Временная1" с атомарной раскладкой таблицы "Состав"

Порядок выполнения:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
 01 
 02 
Пока  20  запрос >  0 
   11 
   12 
   13 
   14 
   15 
Конец Пока

PS: Акс XP
...
Рейтинг: 0 / 0
Подсчет продуктов рецептуры
    #32727748
Iskander68
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для пояснения: см. другой скриншот.
...
Рейтинг: 0 / 0
Подсчет продуктов рецептуры
    #32727810
Фотография Geo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Iskander68
Честно говоря, не вижу принципиальных отличий от приведенных условий, за исключением ввода таблицы "атомов". По условиям, продукт является "атомом", если его не надо готовить - на него нет рецепта. Но даже добавив эту таблицу (не важно, целесообразно это, или нет), вопрос об оптимальном способе расчета количества остается открытым и неизменным.

2 paparome
Угумсь, благодарствую. Под вторым вариантом я примерно это и имел в виду.

В принципе, общее количество можно и одним запросом собрать, но это сразу ограничит количество уровней вложенности рецептов.
...
Рейтинг: 0 / 0
Подсчет продуктов рецептуры
    #32727937
Фотография paparome
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Geo2 Iskander68
Честно говоря, не вижу принципиальных отличий от приведенных условий, за исключением ввода таблицы "атомов". По условиям, продукт является "атомом", если его не надо готовить - на него нет рецепта. Но даже добавив эту таблицу (не важно, целесообразно это, или нет), вопрос об оптимальном способе расчета количества остается открытым и неизменным.

2 paparome
Угумсь, благодарствую. Под вторым вариантом я примерно это и имел в виду.

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

Причем стоит заметить, что в случае со временной таблицей ее пересчетом не требуется заниматься при каждом расчете затрат товара на определенный день, а только в момент пополнения "репертуара" повара
...
Рейтинг: 0 / 0
Подсчет продуктов рецептуры
    #32727973
Фотография Geo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
paparomeПричем стоит заметить, что в случае со временной таблицей ее пересчетом не требуется заниматься при каждом расчете затрат товара на определенный день, а только в момент пополнения "репертуара" повара
Вот не знаю. Добавлю, что рецептов будут тысячи, каждый из них меняется день ото дня, в зависимости от наличия или отсутствия тех или иных продуктов посредством калькуляции. Так что "пополнение репертуара" будет чуть ли не ежедневно. Хранить расход продуктов на единицу рецепта, при том, что придется хранить расход продуктов на все меню - в такой ситуации это совсем не есть хорошо.
...
Рейтинг: 0 / 0
Подсчет продуктов рецептуры
    #32728024
Фотография paparome
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Geo paparomeПричем стоит заметить, что в случае со временной таблицей ее пересчетом не требуется заниматься при каждом расчете затрат товара на определенный день, а только в момент пополнения "репертуара" повара
Вот не знаю. Добавлю, что рецептов будут тысячи, каждый из них меняется день ото дня, в зависимости от наличия или отсутствия тех или иных продуктов посредством калькуляции. Так что "пополнение репертуара" будет чуть ли не ежедневно. Хранить расход продуктов на единицу рецепта, при том, что придется хранить расход продуктов на все меню - в такой ситуации это совсем не есть хорошо.

Тогда немного переделай запрос 02 и будет тебе счастье :)

Код: plaintext
1.
2.
3.
INSERT INTO Временная1 ( id_tovar, id_komponent, kolvo, is_multi )
SELECT Состав.id_tovar, Состав.id_komponent, Состав.kolvo*Меню.kolvo AS kolvo, Товары.is_multi
FROM Товары INNER JOIN (Дни INNER JOIN (Меню INNER JOIN Состав ON Меню.id_tovar = Состав.id_tovar) ON Дни.id = Меню.id_date) ON Товары.id = Состав.id_komponent
WHERE (((Дни.date_day)=Date()));
...
Рейтинг: 0 / 0
Подсчет продуктов рецептуры
    #32728028
Фотография Geo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
:) Запросы все равно будут сильно отличаться. Мне интересно, какой способ лучше выбрать.
...
Рейтинг: 0 / 0
Подсчет продуктов рецептуры
    #32728159
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GeoЕсть задачка:

Существует, скажем, меню на день:
Блюдо КоличествоСуп 10Рис 10
Есть таблица рецепт ов:
Код блюда Код товара Количество (закладка)Суп Бульон 1Суп Мясо 0.01Бульон Вода 1Бульон Мясо 0.01Рис Крупа рисовая 1
Т.е. каждый товар рецепта в свою очередь тоже может являться рецептом.

Надо сосчитать количество продуктов на меню:
Продукт КоличествоВода 10Мясо 0.2Крупа рисовая 10

Видно, сегодня не мой день...
Никак в толк взять не могу, почему
SELECT [Код товара], SUM([Количество(закладка)])
FROM рецептов AS TS
WHERE
NOT EXISTS(
SELECT [Код товара] FROM рецептов
WHERE [Код товара]=TS.[Код товара]
)
GROUP BY [Код товара]
не проходит?

Можно и через левый джойн нарисовать

Кажется от "уровня вложенности" это не зависит.

Что я не понял?
...
Рейтинг: 0 / 0
Подсчет продуктов рецептуры
    #32728294
Фотография Geo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
запрос
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
SELECT [Код товара], SUM([Количество(закладка)])
FROM рецептов AS TS
WHERE
NOT EXISTS(
SELECT [Код товара] FROM рецептов 
WHERE [Код товара]=TS.[Код товара]
)
GROUP BY [Код товара]
Неверен по условию - он смотрит на содержимое таблицы рецептов, а меню будет содержать лишь несколько из известных рецептов. Если его немножко переделать (вероятно, поправить ошибку):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
SELECT [Код товара], SUM([Количество(закладка)]*меню.количество)
FROM рецептов AS TS 
     INNER JOIN меню ON TS.[Код блюда] = меню.Блюдо
WHERE
NOT EXISTS(
SELECT [Код товара] FROM рецептов 
WHERE [Код товара]=TS.[Код товара]
)
GROUP BY [Код товара]
, то он будет давать неверный результат.

Например, дано:
Меню
Блюдо КоличествоКотлета 10
Рецепты
Блюдо Продукт КоличествоКотлета Фарш 1Котлета Соль 0.001Фарш Мясо отварное 2Фарш Хлеб 1Фарш Соль 0.001Мясо отварное Говядина 1
Должен быть получен результат:
Продукт КоличествоСоль 0.02Хлеб 10Говядина 20
А такой запрос вернет:
Продукт КоличествоСоль 0.01
Т.е. не совсем котлеты. Вернее, совсем не котлеты...
...
Рейтинг: 0 / 0
Подсчет продуктов рецептуры
    #32728331
Andrew O
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
На самом деле в этой задачке должна быть всего одна таблица которая включает все инградиенты как простые так и составные. Составные должны быть связаны с простыми по какому то индетификатору отношением "один ко многим". так как простые не будут иметь связь по ним можно раскрутить всю цепочку. Вот принцип, когда-то я это уже делал... Найду пришлю...
...
Рейтинг: 0 / 0
Подсчет продуктов рецептуры
    #32728355
Фотография Geo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторНа самом деле в этой задачке должна быть всего одна таблица которая включает все инградиенты как простые так и составные.

А в условии разве по-другому? Да и вариант Iskander'а не сильно отличается от этого утверждения.

Сейчас меня интересуют только общие принципы, а не готовые решения, поэтому присылать, наверное, не стоит. Я тоже это уже делал и работает. Только я сделал рекурсивно, и мне не нравится, как оно стало работать на более-менее приличных объемах. Поэтому ищу способ лучше. Пока остановился на варианте с временной таблицей.

Если есть другие способы, буду рад послушать о них и покритиковать, а также послушать критику описанных мною :))
...
Рейтинг: 0 / 0
Подсчет продуктов рецептуры
    #32728374
Фотография Geo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Виктоша
GeoА такой запрос вернет:
Продукт КоличествоСоль 0.01
Т.е. не совсем котлеты. Вернее, совсем не котлеты...
Кстати, оригинал скажет:
Продукт КоличествоСоль 0.002Говядина 1Хлеб 1
...
Рейтинг: 0 / 0
Подсчет продуктов рецептуры
    #32728420
SRG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SRG
Гость
GEOОткрывать по рекордсету на каждый уровень вложенности рекурсии, мне кажется, очень плохо - кушает память, и натыкается на разнообразные ограничения акцесса (кол-во одновременно открытых таблиц и т.д).


А что если, к примеру (для a97):
- открыть 1 рекордсет acTable,
- установить .Index="<по полю КодБлюда>" :
- Дальше:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
.seek("=",varКодБлюда)
if .nomatch then
else
  do
    varBmk=.bookmark
     '*********** 
    здесь обработка + рекурсия
 
     '*********** 
    .bookmark=varbmk
    .movenext
    if .eof then exit do
    if !КодБлюда <>varКодБлюда then exit do
  loop
endif

?
...
Рейтинг: 0 / 0
Подсчет продуктов рецептуры
    #32728445
aleks2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
При правильных индексах - будет считать быстро.

Это все переносимо на MDB без проблем.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
CREATE TABLE [меню] (
	[ID] [int] IDENTITY ( 1 ,  1 ) NOT NULL ,
	[Блюдо] [char] ( 50 ) COLLATE Cyrillic_General_CI_AS NOT NULL ,
	[Количество] [char] ( 50 ) COLLATE Cyrillic_General_CI_AS NOT NULL ,
	CONSTRAINT [PK_меню] PRIMARY KEY  CLUSTERED 
	(
		[ID]
	)  ON [PRIMARY] 
) ON [PRIMARY]
GO

CREATE TABLE [рецепты] (
	[ID] [int] IDENTITY ( 1 ,  1 ) NOT NULL ,
	[Блюдо] [char] ( 50 ) COLLATE Cyrillic_General_CI_AS NOT NULL ,
	[Компонент] [char] ( 50 ) COLLATE Cyrillic_General_CI_AS NOT NULL ,
	[Количество] [float] NOT NULL ,
	CONSTRAINT [PK_рецепты] PRIMARY KEY  CLUSTERED 
	(
		[ID]
	)  ON [PRIMARY] 
) ON [PRIMARY]
GO

CREATE TABLE [Расчет] (
	[ID] [int] IDENTITY ( 1 ,  1 ) NOT NULL ,
	[Продукт] [char] ( 50 ) COLLATE Cyrillic_General_CI_AS NOT NULL ,
	[Количество] [float] NOT NULL ,
	[Level] [int] NOT NULL CONSTRAINT [DF_Расчет_Level] DEFAULT ( 0 ),
	CONSTRAINT [PK_Расчет] PRIMARY KEY  CLUSTERED 
	(
		[ID]
	)  ON [PRIMARY] 
) ON [PRIMARY]
GO

CREATE VIEW dbo.m_Decode
AS
SELECT     C.Продукт, R.Компонент, C.Количество * R.Количество AS Количество, C.[Level]
FROM         dbo.Расчет C INNER JOIN
                      dbo.рецепты R ON C.Продукт = R.Блюдо
GO

CREATE VIEW dbo.m_Result
AS
SELECT     dbo.рецепты.Компонент, SUM(dbo.Расчет.Количество) AS Количество
FROM         dbo.Расчет INNER JOIN
                      dbo.рецепты ON dbo.Расчет.Продукт = dbo.рецепты.Компонент LEFT OUTER JOIN
                      dbo.рецепты рецепты_1 ON dbo.рецепты.Компонент = рецепты_1.Блюдо
WHERE     (рецепты_1.ID IS NULL)
GROUP BY dbo.рецепты.Компонент
GO

-- это надо переписать на VBA
CREATE PROCEDURE m_Calculate
AS
set nocount on

TRUNCATE TABLE dbo.Расчет 

INSERT INTO dbo.Расчет (Продукт, Количество)
SELECT     Блюдо, Количество
FROM         dbo.меню

declare @l int
set @l= 0 
while exists(select * from dbo.m_Decode where [Level]=@l) begin
    INSERT INTO dbo.Расчет (Продукт, Количество,[Level])
    SELECT     Компонент, Количество, [Level]+ 1 
    FROM         dbo.m_Decode where [Level]=@l
    set @l=@l+ 1 
end

select * from dbo.m_Result
RETURN 

...
Рейтинг: 0 / 0
Подсчет продуктов рецептуры
    #32728457
Фотография Geo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тогда все равно придется где-то собирать накопления - в массиве (не хочу, ибо неизвесно заранее, какой размер его потребуется) либо в таблице. А в последнем случае можно запросом пройтись по каждому уровню рекурсии, как в варианте paparome. Запрос будет работать быстрее.
...
Рейтинг: 0 / 0
Подсчет продуктов рецептуры
    #32728472
Фотография Geo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Предыдущий мой пост был 2 SRG.

2 Алекс2

Cпасибо.
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Подсчет продуктов рецептуры
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]