Здравствуйте все.
Подскажите как в скрипте получить доступ к данным сохраненного плана и факта определенного Планирования?
Я решаю такую задачу: пересчитывать автоматически план одного планирования на основании данных другого. Пробую сделать функцию CalcPlan на подобие function Calc(Planning, DimensionKey, OnlyDimensionID) в скрипте scr_PlanningCalcUtils.
Застряла на том, что надо открыть известное родительское планирование, и получить оттуда сохраненные значения. Измерения планирований совпадают.
Нравится
Виктория,
результаты планирования пересчитываются каждый раз заново и сохраняются в Мемори Датасет, который очищается после закрытия программы.
То есть, если Вам необходимо получить значения другого планирования, есть два варианта решения:
1. Сохранять эти значения при каждом пересчете в определенную таблицу
2. Делать фоновый пересчет и складывать результат в другой мемори датасет, а потом выбирать значения из него.
Преимущества первого метода - легче в отладке, т.к. можно привязываться к конкретным названиям полей мемори датасета.
Преимущества второго - не нагружается лишний раз база данных.
В обоих случаях задача является крайне сложной в реализации из-за гибкости настроек планирования.
Фактически, сотруднику надо запретить менять родительский план (включая период планирования) иначе дочерний план функционировать перестанет.
Я и не пытаюсь сделать универсальный метод пересчета планов. Ведь может изменяться кол-во измерений, показатели могут планироваться и не планироваться, могут быть планирования с несколькими показателями, формулы пересчета планов могут быть сложными и тд.
Моя изначальная задача выглядит так: еженедельно перепланировать 1 показатель на основании факта, и видеть как для 20 других тоже изменятся планы (это такие прогнозы по этим показателям). Факт по всем показателям у меня считается в ТС, планы мне тоже надо сообщать в ТС, чтобы все пользователи могли их видеть. А вот пересчет по формулам я могу организовать только в Excel.
Поэтому я хочу заложить известный механизм пересчета планов в скрипт. Иначе моя работа будет такой: пересчитать факты по 21 планированию, потом занести факт в Excel, потом пересчитать в Excel новые планы, заполнить полученные планы по 20 показателям по-недельно на полгода вперед. В таком виде это занимает очень много времени.
Я понимаю, что мое решение не будет гибким в настройке, и его работа будет основываться на уже созданных планированиях, которые нельзя будет изменять (измерения, показатели, периоды).
Но настройки планирования меняю только я, поэтому на результат это не повлияет.
Расчитывать планы я собираюсь также в строгой последовательности.
Теперь о моем вопросе: у меня уже есть сохранненные план и факт родительского планирования, зачем еще раз его пересчитывать и куда-то сохранять?
Мне необходимо как-то получить доступ к этим уже сохранненным данным. Вот тут и возникла проблема.
Виктория, в том-то и дело, что сохраненные есть только настройки. Ваши дочерние лпаны зависят от настроек?
Если так, тогда их можно получить из ds_PlanningData
если все-таки высчитанное значение, то оно рассчитывается каждый раз заново. И тут уже есть нюансы.
Пересчет выполняется при показе планирования в скрипте wnd_PlanningViewGridScript. Оттуда можно получить скрипты, которые производят расчет.
1. Что-то я запуталась. Я вижу, что пересчет факта происходит только при нажатии кнопки "Пересчитать" (скрипт действительно wnd_PlanningViewGridScript). Но если ее не нажимать, то значения факта заполняются старыми значениями, которые были ранее высчитаны. Значит они хранятся где-то ( а именно в ds_PlanningData). А план так точно хранится. Это так для всех планирований. Мне не понятно в чем различие , о котором Вы говорите.
2. Вопрос, на который я не могу найти ответ: как получить массив со всеми данными PlanningValue по всеми измерениям и периодам для известного планирования?
Виктория, самые последние расчитанные значения содержатся в tbl_PlanningData (могут быть получены из ds_PlanningData соответственно).
Колонки называются PlanningValue и ActualValue
Получить необходимое значение можно отфильтровав по PlanningID. В отфильтрованном датасете необходимо выбирать самое последнее значение, т.к. старые значения не затираются.
Получить идентификатор нужного планировани можно из датасета ds_Planning
Анна, наверное, я как-то неправильно формулирую свой вопрос.
Я попробую еще раз: как , зная ID планирования, ID измерения, ID периода сформировать массив фактических значений ?
Я не знала как написать такой скрипт. С последнего моего сообщения я продвинулась в этом вопросе
var ParentDataDataset = GetSingleItemByCode('ds_PlanningData'); ApplyDatasetFilter(ParentDataDataset, 'PlanningID', '{A8D5F91D-2A19-4E02-8471-E829FAA818CB}', true); ApplyDatasetFilter(ParentDataDataset, 'PlanningDimensionID','{DECC77D9-6D0C-4158-89E1-00FE1F937FD2}', true); var ActualValue = GetNewDictionary(); for (Key in Planning.Periods) { System.ProcessMessages(); Period = Planning.Periods[Key]; Log.Write(1,Period.BeginDate) ; ApplyDatasetFilter(ParentDataDataset, 'Period', Period.BeginDate, true); ParentDataDataset.Open(); var X= ParentDataDataset.Values('ActualValue'); Log.Write(1,X) ; ActualValue.Add(X, Period.BeginDate); ParentDataDataset.Close(); ApplyDatasetFilter(ParentDataDataset, 'Period', Period.BeginDate, false); }
Но , в таком моем варианте я получаю результат: Дата первого периода, Факт.значение по этому периоду, и на второй итерации Дата второго периода и ... все. Ошибку выдает на строке var X= ParentDataDataset.Values('ActualValue');
Я применяю этот скрипт на дочернем планировании, в котором отмечено для просмотра 3 периода.
Виктория,
а какую ошибку выдает? Что при этом в датасете ParentDataDataset? Откуда берется Period.BeginDate?
Если в результате фильтрации датасет пуст, то в ParentDataDataset.Values('ActualValue') NULL и скрипт работать не будет.
В любом случае, если происходит ошибка, необходима отладка для выяснения причин ошибки.
Попробуйте перетянуть ParentDataDataset.Values('ActualValue') в watch отладчика и посмотреть содержимое.
Ошибку не выдает, на второй итерации цикла останавливается на строке Log.Write(1,X) ;
Проблемы с Period.BeginDate нет. Даты начала каждого периода берутся из моего текущего открытого (дочернего) планирования . И в лог эти даты выводятся правильно.
ParentDataDataset не пуст хотя бы на первой итерации, ведь значение факта я получаю, и оно выводится в лог.
НО: возможно надо как-то по другому отменить фильтр по первой дате ? чтобы потом во второй итерации накладывать фильтр на изначальный датасет? я имею ввиду строку ApplyDatasetFilter(ParentDataDataset, 'Period', Period.BeginDate, false);
Если фильтр не отменен, то выходит, что фильтр по дате начала периода применяется 2 раза, а значит на второй итерации - датасет действительно пуст....
Как правильно отменить этот фильтр?
ApplyDatasetFilter(ParentDataDataset, 'Period', Period.BeginDate, true);
Этот фильтр не работает, потому что ему передают значние другого типа, чем тип поля.
То есть, в tbl_PlanningData в поле Period хранится дата последнего пересчета. И по ней фильтровать не надо.
Фильтровать надо по PlanningID, а потом становиться на последнюю запись датасета методом Dataset.GotoLast();
Ой, что-то я запуталась , уже практически окончательно. И мне очень нужна помощь, чтобы с этим разобраться.
Что надо: получить рассчитанное значение факта для 1периода, для 2ого периода, и тд (для всех тех периодов, которые открыты в дочернем планировании. Например, неделя 40, 41, и 42) из родительского планирования.
Что есть: у меня есть Даты начала (Period.BeginDate ) этих нескольких периодов (Например, даты 3.10.11, 10.10.11 и 17.10.11) . ID родительского планирования у меня тоже есть, также известны ID измерения и то, что в этом планировании всего один показатель, который планируется.
Теперь вопросы:
1. Моя логика такая: на основании этих данных я должна иметь возможность получить информацию о факте, который хранится в таблице tbl_PlanningData.
В указанной таблице есть ID, PlanningID, Period, PlanningDemensionID, DemensionID, DemensionID, PlanningValue, ActualValue. (где Period - дата последнего пересчета?).
Т.е. получатся , что в этой таблице нет указания на период, к которому относится сохраненная запись.
Но ведь связь между этой таблицей и периодом все же где-то должна существовать.
Так где же указано это соответствие? Какой датасет надо фильтровать?
2. Могу предположить , что Даты начала периода (который я получила из дочернего планирования) может быть недостаточно для организации такого фильтра. Тогда возникнет второй вопрос
Как по дате начала Period.BeginDate найти некое ParentPeriodID родительского планирования, соответствующее такой дате начала? в какой таблице и соответствующем датасете хранится это отношение?
"Тихенко Виктория" написал:
1. Моя логика такая: на основании этих данных я должна иметь возможность получить информацию о факте, который хранится в таблице tbl_PlanningData.
В указанной таблице есть ID, PlanningID, Period, PlanningDemensionID, DemensionID, DemensionID, PlanningValue, ActualValue. (где Period - дата последнего пересчета?).
Т.е. получатся , что в этой таблице нет указания на период, к которому относится сохраненная запись.
Но ведь связь между этой таблицей и периодом все же где-то должна существовать.
Так где же указано это соответствие? Какой датасет надо фильтровать?
В таблице tbl_PlanningData хранятся только те периоды, которые были явно пересчитаны. Остальные не хранятся. Периоды в данной таблице тоже не хранятся, они берутся единоразово из Мемори Датасета mds_PlanningPeriod, который генерируется каждый раз в зависимости от настроек планирования.
Т.е. вытащить периоды теоретически можно из настроек планирования. Но тогда нужно сначала принудительно пересчитывать планы, потом использовать их в дочерних.
"Тихенко Виктория" написал:2. Могу предположить , что Даты начала периода (который я получила из дочернего планирования) может быть недостаточно для организации такого фильтра. Тогда возникнет второй вопрос
Как по дате начала Period.BeginDate найти некое ParentPeriodID родительского планирования, соответствующее такой дате начала? в какой таблице и соответствующем датасете хранится это отношение?
Даты начала и конца генерируются в скрипте mds_PlanningPeriodScript и хранятся в мемори датасете до закрытия датасета.