Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Подсчет продуктов рецептуры / 20 сообщений из 20, страница 1 из 1
07.10.2004, 11:07:26
    #32727479
Geo
Geo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подсчет продуктов рецептуры
Есть задачка:

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

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

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

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

Никто не решал такую задачу? М.б. есть красивше способы?
...
Рейтинг: 0 / 0
07.10.2004, 11:18:08
    #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
07.10.2004, 11:23:21
    #32727529
Geo
Geo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подсчет продуктов рецептуры
А собственно требуемое и забыл написать :(
Ну это я поправил.

2 Iskander
авторА есть ли необходимость объединять в одну таблицу ингридиенты ("товары" - суп) и "подингридиенты" (вода)? Может стоит рассмотреть создание новой таблицы, где бульон будет расписан на "атомарные" ингридиенты - вода, мясо и
т.д.?
Конечно. Такая таблица есть - называется "рецепты". В ней бульон расписан на воду и мясо. А вот суп на воду и мясо расписать не получится - в него помимо прочего входит именно "бульон", а не составляющие последнего.
...
Рейтинг: 0 / 0
07.10.2004, 12:25:08
    #32727724
Iskander68
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подсчет продуктов рецептуры
Ну у меня вот что получилось. Пять таблиц. См. скриншот. Бульон есть и в блюдах (Meals) и в Ингридиентах (Ingredients). Бульон как блюдо состоит из бульона как ингридиента, а тот в свою очередь из атомов (вода, мясо). Вода и мясо есть и в ингридиентах, и в атомах. Не знаю, правда, чем это лучше рекурсии :-)
...
Рейтинг: 0 / 0
07.10.2004, 12:27:44
    #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
07.10.2004, 12:31:23
    #32727748
Iskander68
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подсчет продуктов рецептуры
Для пояснения: см. другой скриншот.
...
Рейтинг: 0 / 0
07.10.2004, 12:47:01
    #32727810
Geo
Geo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подсчет продуктов рецептуры
2 Iskander68
Честно говоря, не вижу принципиальных отличий от приведенных условий, за исключением ввода таблицы "атомов". По условиям, продукт является "атомом", если его не надо готовить - на него нет рецепта. Но даже добавив эту таблицу (не важно, целесообразно это, или нет), вопрос об оптимальном способе расчета количества остается открытым и неизменным.

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

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

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

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

Причем стоит заметить, что в случае со временной таблицей ее пересчетом не требуется заниматься при каждом расчете затрат товара на определенный день, а только в момент пополнения "репертуара" повара
...
Рейтинг: 0 / 0
07.10.2004, 13:30:37
    #32727973
Geo
Geo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подсчет продуктов рецептуры
paparomeПричем стоит заметить, что в случае со временной таблицей ее пересчетом не требуется заниматься при каждом расчете затрат товара на определенный день, а только в момент пополнения "репертуара" повара
Вот не знаю. Добавлю, что рецептов будут тысячи, каждый из них меняется день ото дня, в зависимости от наличия или отсутствия тех или иных продуктов посредством калькуляции. Так что "пополнение репертуара" будет чуть ли не ежедневно. Хранить расход продуктов на единицу рецепта, при том, что придется хранить расход продуктов на все меню - в такой ситуации это совсем не есть хорошо.
...
Рейтинг: 0 / 0
07.10.2004, 13:46:54
    #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
07.10.2004, 13:48:13
    #32728028
Geo
Geo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подсчет продуктов рецептуры
:) Запросы все равно будут сильно отличаться. Мне интересно, какой способ лучше выбрать.
...
Рейтинг: 0 / 0
07.10.2004, 15:20:49
    #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
07.10.2004, 16:04:51
    #32728294
Geo
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
07.10.2004, 16:13:19
    #32728331
Andrew O
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подсчет продуктов рецептуры
На самом деле в этой задачке должна быть всего одна таблица которая включает все инградиенты как простые так и составные. Составные должны быть связаны с простыми по какому то индетификатору отношением "один ко многим". так как простые не будут иметь связь по ним можно раскрутить всю цепочку. Вот принцип, когда-то я это уже делал... Найду пришлю...
...
Рейтинг: 0 / 0
07.10.2004, 16:21:09
    #32728355
Geo
Geo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подсчет продуктов рецептуры
авторНа самом деле в этой задачке должна быть всего одна таблица которая включает все инградиенты как простые так и составные.

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

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

Если есть другие способы, буду рад послушать о них и покритиковать, а также послушать критику описанных мною :))
...
Рейтинг: 0 / 0
07.10.2004, 16:26:47
    #32728374
Geo
Geo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подсчет продуктов рецептуры
2 Виктоша
GeoА такой запрос вернет:
Продукт КоличествоСоль 0.01
Т.е. не совсем котлеты. Вернее, совсем не котлеты...
Кстати, оригинал скажет:
Продукт КоличествоСоль 0.002Говядина 1Хлеб 1
...
Рейтинг: 0 / 0
07.10.2004, 16:41:48
    #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
07.10.2004, 16:49:50
    #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
07.10.2004, 16:51:45
    #32728457
Geo
Geo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подсчет продуктов рецептуры
Тогда все равно придется где-то собирать накопления - в массиве (не хочу, ибо неизвесно заранее, какой размер его потребуется) либо в таблице. А в последнем случае можно запросом пройтись по каждому уровню рекурсии, как в варианте paparome. Запрос будет работать быстрее.
...
Рейтинг: 0 / 0
07.10.2004, 16:56:35
    #32728472
Geo
Geo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подсчет продуктов рецептуры
Предыдущий мой пост был 2 SRG.

2 Алекс2

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


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