Всем привет, нужна помощь с разработкой отчета FastReport.

Создал скрипт по вызову FastReport-отчета по кнопке. На клиентском компьютере после 2-3х использований функции вылетает ошибка "разрушительный сбой". Строка на которой все рушится:

var ReportPreviewer = Services.GetNewItemByUSI('wnd_BaseFastReportPreview');

Проблема явно в этой строке, т.к. если скрываю в /* */ весь остальной код ошибка остается, а если наоборот (оставить только неё) я получаю сбой. Debugger-ом пройтись не удастся, на клиентском компьютере нет VS.

Нравится

2 комментария

Здравствуйте, Иван!

Как писала Наталья Бондарь в рамках обращения 0210495, попробуйте заменить

Services.GetNewItemByUSI('wnd_BaseFastReportPreview');
на
Services.GetSingleItemByUSI('wnd_BaseFastReportPreview');

Если это не даст результат, направьте по обращению сервисы отчета.

Вроде бы помогло. Спасибо!

Показать все комментарии

Всем доброго времени суток, необходима помощь по решению проблемы с wnd_BaseFastReportPreview. Суть следующая:

Разработал скрипт по экспорту отчета в FastReport по нажатию на кнопку. На моей базе все отлично, на компьютере клиента после 2-3х вызовов функции вываливается ошибка "Разрушительный сбой". Нашел проблемную строку:

var ReportPreviewer = Services.GetNewItemByUSI('wnd_BaseFastReportPreview');

Дело наверняка в ней, т.к. закомментировав весь код функции кроме этой строчки я получаю ту же самую ошибку (и наоборот - 'спрятав' все кроме её и производных от неё я получаю log-и и могу дальше работать в программе). Права у клиента полные, кэш приложения пуст, пройтись debugger-ом вряд ли получится возможным.

Кто нибудь сталкивался с подобной проблемой?

Нравится

1 комментарий

Есть запрос в котором нужно фильтровать данные по незаполненным полям в БД.
На форме фильтрации есть чекбоксы, при выбранном чексе будет включаться фильтн на is null.

var DatasetUSIList = ReportPreviewer.Report.Attributes('DatasetUSIList');
       
        for (var i = 0; i DatasetUSIList.length; i++) {
            var ReportDatasetUSI = DatasetUSIList[i];
            var ReportDataset = ReportPreviewer.DatasetByUSI(ReportDatasetUSI);
            ReportDataset.Close();
               
                ApplyDatasetFilter(ReportDataset, 'FromDate', FromDate, FromDateFilterEnabled);
                ApplyDatasetFilter(ReportDataset, 'ToDate', ToDate, ToDateFilterEnabled);
                                                                               
        var BranchIDs = edtBranchIDs.Tag.split(',');
                ApplyDatasetIncludeFilter(ReportDataset, 'BranchIDs', BranchIDs, BranchFilterEnabled);         
               
                var OwnerIDs = edtOwnerIDs.Tag.split(',');
                ApplyDatasetIncludeFilter(ReportDataset, 'OwnerIDs', OwnerIDs, OwnerFilterEnabled);              
               
                //Включение доп параметров
                if(Fields.IsChecked != false){
                        EnableDatasetFilters(ReportDataset, true, 'FieldsIDin');
        }
                //             
        }

Но в скрипте я его немогу включить. Подскажите что я делаю не так?

Нравится

3 комментария

Не понятно, т.е. код в скрипте отрабатывает, но фильтры в запрос не добавляются?

"Олейник Дмитрий" написал:

Не понятно, т.е. код в скрипте отрабатывает, но фильтры в запрос не добавляются?

С уважением,

Олейник Дмитрий


Совершенно верно, так как параметры находятся в подзапросе, и как к ним добраться я не знаю!

Ну, значение параметра можно установить так:

SetParameterValue(myDataset.SelectQuery.Parameters, 'myParamName', 'myParamValue');

А включить фильтр в подзапросе можно либо сразу же в сервисе, либо вручную:

myDataset.SelectQuery.Items(0).Filters.ItemsByName('myFilter').IsEnabled = true;
Показать все комментарии

Подскажите, как можно вывести примерно такой запрос полностью в любой тип отчета, который возможен:

DROP TABLE ##t
select ROW_NUMBER() over (order by [CreatedOn] DESC) as rn, [ID], [CreatedOn], [BasicPrice],OfferingID,RecordID,OfferingName INTO ##t
        from [tbl_OfferingPriceLog]
         WHERE PriceCategoryID = 'B46B83EF-39AD-4687-B375-AB60EF931309'
------------------------------------------------------
DROP TABLE ##m
SELECT A.[ID] ,A.[CreatedOn] ,A.[BasicPrice],A.OfferingID
      ,ISNULL(A.[BasicPrice] - (select top 1 b.[BasicPrice] from ##t B,0) AS DELTAPRICE,
      CASE WHEN ISNULL(A.[BasicPrice] - (select top 1 b.[BasicPrice] from ##t B,0) = 0 THEN 0 ELSE
       1 END AS COUNTDELTA INTO ##m
  FROM ##t A
-------------------------------------------------------
  SELECT o.Name AS Name, SUM(a.COUNTDELTA)AS Count
  FROM ##m A
  LEFT OUTER JOIN tbl_Offering o ON o.ID = a.OfferingID
  GROUP BY OfferingID,o.Name
  ORDER BY Count DESC
 -------------------------------------------------------

Нравится

1 комментарий

Добрый день!
Сначала подготовьте таблицу, по которой будете строить отчет (к примеру напишите хранимую процедуру, которую будете запускать из кода, перед построением отчета), а сам отчет уже настройте на эту таблицу.

Показать все комментарии

Добрый день, коллеги.

Не нашел явного решения поэтому прошу помощи в решение задачи.

У нашей компании появилось двое платежных реквизитов. Ранее создавал отчет типа fastreport для формирования отчета "Счет" по определенному юр. лицу (у нас два юр. лица). Теперь у юр. лица (буду его называть "одуван") "одуван" появилось двое платежных реквизитов. В деталях контрагента выбрал основной платежный реквизит. При попытке создать отчет "счет" у меня создается отчет на двух листах с основным платежным реквизитом. Такое происходит, когда только два платежных реквизита. И всегда основным выбирается старый основной платежный реквизит, нового как-будто не видит система.
Что пытался сделать и какие мысли были.
Пытался создать фильтр в fastreport - не работает. Выбирал по полю "Банк". Но тут что-то явно делаю не так
Идея: создать доп.поле в карточке счет. в которое из поисковой карточки или выпадающего поля будет выбираться основной платежный реквизит. Это решение плохо тем, что заставляет делать дополнительные манипуляции сотрудников, а им это не нравится.

В идеале хотелось бы реализации такого типа, что при создании отчета появлялось окно фильтра и там можно было бы выбрать основные платежные реквизиты, которое заполнили бы бланк. Такое вообще возможно, а то у меня сомнения, что так можно? И что проще будет?

Нравится

4 комментария

Забыл уточнить. софт Terrasoft CRM 3.3.2.127

Павел, самым простым вариантом, как по мне, будет следующее:

1. Добавить в карточку платежного реквизита поле "По умолчанию для печати счета" с типом булево.
2. В сервисе sq, который используется для построения отчета, добавить параметр с типом целое число и значением 1, и в блок WHERE добавить уловие:

tbl_AccountBillingInfo.ПоУмолчаниюДляПечатиСчета = Parameter:.ПоУмолчаниюДляПечатиСчета

Тогда при печати счета, будет браться та строка, которая отмечена галочкой "По умолчанию для печати счета".
Но, если такой галочки ни у одной записи не будет - тогда в отчет не попадет ничего.

Если такой вариант не нравится, можно пункт 2 не делать, а просто в дизайнере отчета добавить фильтр по полю "По умолчанию для печати счета", которое если заполнить - в счет попадет строка с отмеченной галочкой, а если не заполнить - строка с не отмеченной галочкой.

Дмитрий,

Правильно ли я Вас понимаю, что во 2-ом (втором) случае логика будет такая: Сотрудник пытается с формировать отчет "Счет" и в случае если настроен соответствующий фильтр, то появится окно-фильтр, в котором сотрудник либо заполнит соответствующее поле и сформируется счет с данными реквизитами банка либо не заполнит и в таком случае выберется платежные реквизиты, которые имеют значение по умолчанию.

Да, все верно.
Фильтры можно преднастроить в сервисе отчета через TS Administrator.

Показать все комментарии

Добрый день! Я новичок, очень нужна помощь.

Ситуация такая:
Создал свое окно для выбора дополнительных параметров отчета Excel. Его открытие происходит в разделе Контакты (wnd_ContactsWorkspace), нажатием Отчеты->"Мой отчет". Как передать Фильтры примененные к Контактам в открытое окно или как их получить из этого окна, для того что бы передать их в запрос допустим sq_Contact.

Нравится

2 комментария

Судя по функции

function ProcessPrepareWordReport(ReportID, QueryID, WorkspaceWindow, IsPreview, RecordIDs) {
    var QueryDataset = GetSingleItemByCode('ds_Query', 'ReportUtils');
    ApplyDatasetIDFilter(QueryDataset, QueryID, true);
    QueryDataset.Open();
	PrepareWordReport(ReportID, QueryDataset, WorkspaceWindow, IsPreview, RecordIDs);
	QueryDataset.Close();
}

вам нужно по кнопке в вашем окне вызывать эту функцию, и в параметр RecordIDs - передать IDшники отфильтрованного источника данных.

Спасибо разобрался уже.

Показать все комментарии

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

Нравится

7 комментариев

Здравствуйте, Николь.

Не совсем понятно, как Вы фиксируете сделки и их результат. Уточните, пожалуйста, этот момент. Какой это раздел, какого типа записи?
Также, необходимо понимать, какой тип отчета Вы хотите использовать? Excel? FastReport?

Продажа должна быть в состоянии Закрыта, у которой заполнено поле Победитель. И продукт, на закладки Продажи, должен быть в позиции Отменено = Ложь.

SELECT
	[tbl_Offering].[Name] AS [Name],
	[tbl_OfferingInOpportunity].[Quantity] AS [Quantity],
	[tbl_OfferingInOpportunity].[IsCanceled] AS [IsCanceled],
	[tbl_Opportunity].[WinnerID] AS [WinnerID],
	[tbl_Opportunity].[Title] AS [Title],
	[tbl_Account].[Name] AS [NameAccount]
FROM
	[dbo].[tbl_OfferingInOpportunity] AS [tbl_OfferingInOpportunity]
LEFT OUTER JOIN
	[dbo].[tbl_Offering] AS [tbl_Offering] ON [tbl_Offering].[ID] = [tbl_OfferingInOpportunity].[OfferingID]
RIGHT OUTER JOIN
	[dbo].[tbl_Opportunity] AS [tbl_Opportunity] ON [tbl_Opportunity].[ID] = [tbl_OfferingInOpportunity].[OpportunityID]
INNER JOIN
	[dbo].[tbl_Account] AS [tbl_Account] ON [tbl_Account].[ID] = [tbl_Opportunity].[WinnerID]
WHERE([tbl_OfferingInOpportunity].[IsCanceled] = :TrueValue AND
	NOT [tbl_Opportunity].[WinnerID] IS NULL)
ORDER BY
	3 ASC,
	1 ASC

Это мой запрос.
Можно ли сделать такой фильтр, чтобы сортировка шла уже в самом запрос?

Здравствуйте, Николь.

Не совсем понятно, как Вы фиксируете сделки и их результат. Уточните, пожалуйста, этот момент. Какой это раздел, какого типа записи?
Также, необходимо понимать, какой тип отчета Вы хотите использовать? Excel? FastReport?

Добрый день.
Хочу попробовать сделать это в FastReport. Результат сделки фиксируется в самой Продаже. Или это не то?

Николь, сложно понять Вашу бизнес-задачу. Скриншот в первом сообщении дате представление об одном, запрос - о другом.
Предлагаю к ознакомлению пример небольшого отчета, который выводит список продуктов и количество побед по продажам Вашей компании и других компаний. Прикрепил сервисы.
sq_nikolreport.rar

Добры день.
Я правильно понимаю, что количество побед - это заполненное в продаже поле Победитель?
И еще вопрос. Менеджеры нашей компании в поле победитель, при победе нашей компании, пишут либо Ваша компания, либо ООО АСТ... Можно ли как-то добавить второй UID в параметр?

Количество побед - это количество продуктов в продажах с заполненным победителем, да.
Можно в sq добавить группу фильтров объединенную логическим ИЛИ и добавить два фильтра сравнения с одним и со вторым идентификатором.

Показать все комментарии

Хочу создать отчет на основе таблицы tbl_OfferingPriceLog. Для этого создаю новый Запрос в Запросах, но при выборе главной таблицы в Запросах такой таблицы (tbl_OfferingPriceLog) нет.
Каким образом таблицы добавляются в Запросы. И можно ли туда добавить Представления?

Нравится

10 комментариев

Alex, пользовательские запросы можно формировать по всем таблицам кроме системных: таблиц логирования (таблицы, которые заканчиваются на Log), таблиц прав доступа (таблицы, которые заканчиваются на Right), таблиц поиска дублей (таблицы, которые заканчиваются на FD).
Ограничение включается через применение фильтра в функции wnd_SelectReportTableOnPrepare сервиса wnd_SelectReportTableScript.
А именно, таким образом:

EnableDatasetFilters(dlData.Dataset, true, 
			'NotRightsTableEx', 'NotLogTableEx', 'ServiceTypeCode');

Пользовательские запросы можно строить по представлениям (если создан сервис таблицы с названием, соответствующим названию представления).

Подскажите, как правильно и в какой последовательности создать сервис таблицы на основе представления, чтобы потом создать Запрос для Отчета.
Я делал так:
1. В БД на основании таблицы tbl_OfferingPriceLog создал представление view_OfferingPriceL.
2. В TSAdmin создаю новый сервис Table. Сохраняю его с именем view_OfferingPriceL (как Вы и говорили, названия должны быть одинаковыми), но сохранять не дает - "Объект с таким именем уже существует".

(Нужно ли ещё для такого Отчета создавать ds и sq?)

Update: Прикрепил пример Отчета, который хочу создать. Возможно есть другие пути создания такого типа Отчетов или может есть шаблоны таких Отчетов?

Alex, Вы все делаете правильно, только когда нажимаете "Сохранить" на предложение системы "обновить структуру таблицы в базе данных" нужно ответить "Нет".

Сервисы ds и sq можно не создавать.

Шаблона приложенного Вами отчета, к сожалению, нет. Реализовать отчет Вы можете как через пользовательский отчет MS Excel, так и через отчет формата FastReport.

Наталия, создал запрос, создал на основе него свой первый отчет (Excel), все работает.
Единственное не могу добиться в запросе, чтобы данные выстраивались по схеме мастер-детэил.
Т.е. сверху ID Продукта, внизу все его изменения. У меня сейчас получилось вверху все ID (все записи), внизу изменение одной (выбранной) записи.
Возможно ли это сделать средствами конфигуратора запросов? Или как-то по другому?
(Представление стандартное:

SELECT   ...
FROM         dbo.tbl_OfferingPriceLog AS tbl_OfferingPriceLog LEFT OUTER JOIN
                      dbo.tbl_Contact AS CreatedBy ON CreatedBy.ID = tbl_OfferingPriceLog.CreatedByID
ORDER BY tbl_OfferingPriceLog.CreatedOn DESC

)

Чтобы данные выстраивались по схеме мастер-детэил достаточно добавить подчиненную деталь по отношению к главной (скриншот прилагаю).

После просмотра вебинара сделал Запрос для Отчета немного по другому:
Master - Таблица tbl_Offering, Detail - таблица вTS на основе представления view_OfferingPriceL.
В MSAdmin в Таблице view_OfferingPriceL создаю связь: Первичный ключ tbl_Offering.ID, вторичный ключ view_OfferingPriceL.OfferingID (связь продукта с изменением). Т.е. выбирая продукт, мы должны получить его изменения.
Иду в Запросы, выбираю главную таблицу tbl_Offering, поле Название.
Добавляю вторую деталь и разворачиваю "Обратные связи", чтобы там найти view_OfferingPriceL и добавить оттуда поля в Деталь2. Но в "Обратные связи" view_OfferingPriceL нету.
Как эту таблицу туда добавить? // И правильный ли у меня алгоритм для этого Отчета?

Alex, выполнила те же действия - таблица в обратных связях появилась.
Вы перезапускали приложение после внесения изменений?

Наталия, а у Вас tbl_OfferingPriceLog - это представление в базе? У меня это представление.
Все перегружал, в связях не появляется.
Может я что-то упустил в настройках?

"Alex GF" написал:Наталия, а у Вас tbl_OfferingPriceLog - это представление в базе?

Нет, таблица.
Завтра проверю с представлением и напишу.

Alex, представления не будут попадать в обратные связи, так как список объектов для обратных связей формируется из БД (а не по внешним связям сервисов).
Если требуется использовать именно представления для формирования отчетов master - detail, нужно будет создать отчет формата FastReport.

Показать все комментарии

Здравствуйте!
Подскажите пожалуйста, есть ли такая возможность, просмотра статистики по использованию отчетов?
Если да, то как это реализовать или где можно посмотреть?

Нравится

6 комментариев

Насколько я понимаю такого нет. Только делать самостоятельно.
А что есть статистика? Кто когда запускал какой отчет?
Или сводные данные типа Отчет 1 - запускался 5 раз...
В любом случае я бы сделал таблицу для логирования вызова и механизм, вносящий в нее данные. Механизм навскидку приходит в голову такой - при каждом вызове отчета (а он делается из раздела через меню Отчеты) писать лог кто, какой отчет, какое время/дата. Куда конкретно вписать вызов логирования сказать с ходу не готов, надо покопаться.
А дальше по необходимости - набор соответствующих сервисов и прицепил бы статистику деталью к разделу отчеты. Либо просто сводный отчет вызывал...

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

Нужно выявить, какими отчетами пользуются постоянно, а какие были созданы и почти не используются. Можно как вариант, считать сколько раз, тот или иной отчет открывался за месяц и заносить эту информацию в таблицу.
Заранее спасибо.

Евгений,
Реализация задачи будет состоять из 2 блоков:
1. Фиксация количества просмотров отчета в таблице.
2. Вывод статистики (в виде пользовательского запроса, детали, отчета и т.д).

Чтобы реализовать первый блок, необходимо (мой вариант):
- Создать таблицу, которая будет содержать поля [Название отчета], [Кол-во просмотров] (дополнительно можно добавить поля, в которых будет фиксироваться период, кто запустил отчет и др.).
- Создать сервисы sq и ds. В sq добавить фильтр сравнения по названию отчета.
- При просмотре отчета (перед отображением) применять фильтр. Если в таблице уже есть запись с таким названием отчета – увеличивать количество просмотров на 1. Если нет – добавлять в таблицу новую запись (фиксировать название отчета, и 1 в поле [Кол-во просмотров]).
Таким образом, Вы сформируете логирование.
Выводить статистику можно различными вариантами: используя пользовательские запросы и отчеты (например, MS Excel), реализовав собственный отчет формата FastReport, посредством детали в разделе [Отчеты].
Если какой-то из приведенных выше пунктов нужно детализировать или привести пример кода, пишите.

Наталья, большое спасибо.
Если я правильно понял, мне надо добавить на событие OnPrepare код, который будет добавлять новую запись в таблицу при открытии отчета? Каким образом будет передаваться данная "единица"? Или каким образом можно передать название отчета в таблицу?
Заранее благодарю.

Передать в таблицу можно:
Получив экземпляр созданного датасета и выполнив Append записи (примеры по поиску Dataset.Append()).
Или прямым инжектом в базу (примеры по поиску InsertQuery.Execute()).

Показать все комментарии

Добрый день!
Как можно отслеживать, кто и когда запускал отчеты и записывать их в таблицу?

Нравится

1 комментарий

Найдите скрипт scr_BaseFastReportPreview
В нем найдите функцию PrepareReport(AWindow)
В ней уже можно дописать функционал добавления записи, ну что-то типа такого:

function PrepareReport(AWindow) {
	CheckAttribute(AWindow, 'Report');
	frpMain.Report = GetAttribute(AWindow, 'Report');
 
	var ReportHistory = Services.GetNewItemByUSI('ds_ReportHistory'); //выбираем датасет куда хотим записать факт вызова отчета
	ReportHistory.Append();
	ReportHistory.('ContactID') = Connector.CurrentUser.ContactID; //Id текущего пользователя, т.е. тот кто вызвал отчет
	ReportHistory('ReportID') = frpMain.Report.ID; //записывает id отчета
	ReportHistory('Date') = new Date(); //дата
	ReportHistory.Post();
	...
}
Показать все комментарии