Скрипты
Разработка

Проблема с Include Filter

sq_Task:

?xml version="1.0" encoding="UTF-8"?>
Service UID="223AC063F8B742FD88E9A75352D0A4B9" USI="X15\Workspaces\Tasks\General\Main Grid\sq_Task" ServiceTypeCode="SelectQuery" Caption="sq_Task">
...
                                Item Code="ParentIDMass" UID="B0B5ADE418C4476C8FDFF663E9B9FB34" Type="IncludeFilter" IsEnabled="False" ExpressionTypeCode="FieldFilterExpression">
                                        TestExpression Type="FieldFilterExpression" FieldSQLName="ParentTaskID" FieldTableUSI="tbl_Task" TableAlias="tbl_Task">
                                        TestExpression>
                                        ValuesExpressions>
                                        ValuesExpressions>
                                Item>
...
Service>

scr_TasksWorkspace:
        IF (chbParent.IsChecked) {
                var ParentID = chParent.Value;
                var ParamValues = new Array(ParentID);
                IF (!IsEmptyValue(ParentID)) {
                        ApplyDatasetIncludeFilter(Dataset, 'ParentIDMass', ParamValues, true, pdtGUID);
                }else{
                        ApplyDatasetIncludeFilter(Dataset, 'ParentIDMass', ParamValues, false, pdtGUID);
                }
        }

scr_DB:
FUNCTION ApplyDatasetIncludeFilter(Dataset, FilterCode, ParamValues, Enabled, DataType) {
        var SELECT = GetSelectQueryPrimarySelect(Dataset.SelectQuery);
        var Filters = SELECT.Filters;
        EnableFilter(Filters, FilterCode, Enabled);
        ApplyQueryIncludeFilter(Dataset.SelectQuery, Filters, FilterCode,
                ParamValues, Enabled, DataType);
        Log.WRITE(1, Connector.DBEngine.GetSelectQuerySQLText(Dataset.SelectQuery));
}

Содержимое лога:
[08.09.30 16.55.55.945] (W)     SELECT
        "tbl_Task"."ID" AS "ID",
        "tbl_Task"."Title" AS "Title",
        "tbl_Task"."DueDate" AS "DueDate",
        "tbl_Task"."CreatedByID" AS "AuthorID",
        "Author"."Name" AS "AuthorName",
        "tbl_Task"."OwnerID" AS "OwnerID",
        "tbl_Task"."AccountID" AS "AccountID",
        "tbl_Account"."Name" AS "AccountName",
        "tbl_Task"."StatusID" AS "StatusID",
        "tbl_TaskStatus"."Status" AS "StatusName",
        "tbl_Task"."ActualStartDate" AS "ActualStartDate",
        "tbl_Task"."ActualFinishDate" AS "ActualFinishDate",
        "tbl_TaskStatus"."Color" AS "StatusColor",
        "tbl_TaskStatus"."IsStart" AS "StatusIsStart",
        "tbl_TaskStatus_old"."IsStart" AS "OldStatusIsStart",
        "tbl_TaskStatus"."IsFinish" AS "StatusIsFinish",
        "tbl_Task"."WorkflowItemID" AS "WorkflowItemID"
FROM
        "tbl_Task" "tbl_Task"
LEFT OUTER JOIN
        "tbl_Contact" AS "Author" ON "Author"."ID" = "tbl_Task"."CreatedByID"
LEFT OUTER JOIN
        "tbl_Account" AS "tbl_Account" ON "tbl_Account"."ID" = "tbl_Task"."AccountID"
LEFT OUTER JOIN
        "tbl_TaskStatus" AS "tbl_TaskStatus" ON "tbl_TaskStatus"."ID" = "tbl_Task"."StatusID"
LEFT OUTER JOIN
        "tbl_TaskStatus" AS "tbl_TaskStatus_old" ON "tbl_TaskStatus_old"."ID" = "tbl_Task"."OldStatusID"
WHERE
        (((("tbl_Task"."StartDate" :ToDate AND
        ("tbl_Task"."DueDate" >= :StartDate OR
        "tbl_Task"."ActualFinishDate" >= :StartDate)) OR
        ("tbl_Task"."DueDate" :CurrentDate AND
        "tbl_TaskStatus"."IsFinish" > :IsFinish)) AND
        NOT "tbl_TaskStatus"."IsFinish" = :True AND
        NOT "tbl_TaskStatus"."IsStop" = :True AND
        NOT "tbl_TaskStatus"."IsReject" = :True))
ORDER BY
        10 ASC
ROWS    1       TO      40
[08.09.30 16.56.02.273] (W)     SELECT
        "tbl_Task"."ID" AS "ID",
        "tbl_Task"."Title" AS "Title",
        "tbl_Task"."DueDate" AS "DueDate",
        "tbl_Task"."CreatedByID" AS "AuthorID",
        "Author"."Name" AS "AuthorName",
        "tbl_Task"."OwnerID" AS "OwnerID",
        "tbl_Task"."AccountID" AS "AccountID",
        "tbl_Account"."Name" AS "AccountName",
        "tbl_Task"."StatusID" AS "StatusID",
        "tbl_TaskStatus"."Status" AS "StatusName",
        "tbl_Task"."ActualStartDate" AS "ActualStartDate",
        "tbl_Task"."ActualFinishDate" AS "ActualFinishDate",
        "tbl_TaskStatus"."Color" AS "StatusColor",
        "tbl_TaskStatus"."IsStart" AS "StatusIsStart",
        "tbl_TaskStatus_old"."IsStart" AS "OldStatusIsStart",
        "tbl_TaskStatus"."IsFinish" AS "StatusIsFinish",
        "tbl_Task"."WorkflowItemID" AS "WorkflowItemID"
FROM
        "tbl_Task" "tbl_Task"
LEFT OUTER JOIN
        "tbl_Contact" AS "Author" ON "Author"."ID" = "tbl_Task"."CreatedByID"
LEFT OUTER JOIN
        "tbl_Account" AS "tbl_Account" ON "tbl_Account"."ID" = "tbl_Task"."AccountID"
LEFT OUTER JOIN
        "tbl_TaskStatus" AS "tbl_TaskStatus" ON "tbl_TaskStatus"."ID" = "tbl_Task"."StatusID"
LEFT OUTER JOIN
        "tbl_TaskStatus" AS "tbl_TaskStatus_old" ON "tbl_TaskStatus_old"."ID" = "tbl_Task"."OldStatusID"
WHERE
        (((("tbl_Task"."StartDate" :ToDate AND
        ("tbl_Task"."DueDate" >= :StartDate OR
        "tbl_Task"."ActualFinishDate" >= :StartDate)) OR
        ("tbl_Task"."DueDate" :CurrentDate AND
        "tbl_TaskStatus"."IsFinish" > :IsFinish)) AND
        NOT "tbl_TaskStatus"."IsFinish" = :True AND
        NOT "tbl_TaskStatus"."IsStop" = :True AND
        NOT "tbl_TaskStatus"."IsReject" = :True AND
        "tbl_Task"."ParentTaskID" IN ()))
ORDER BY
        10 ASC
ROWS    1       TO      40

Первая запись без фильтра, вторая с фильтром.
При включении фильтрации возникает ошибка:
...
SQL error code = -104
...
Error code: 249

Что я не так делаю?

Нравится

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

Добрый день, Константин.

Внешне все правильно:
1) фильтр создан правильно
2) функция наложения фильтра реализована и вызывается верно,

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

[javascript]
function ApplyQueryIncludeFilter(Query, Filters, FilterCode, ParamValues, Enabled,
DataType) {
// TODO
// Переписать - временное решение
// Усовершенствовать для работы с вложенными SelectQuery
// Удалять созданные параметры
// Передавать тип параметров
// Генерировать нормальное имя ParamExpression
if ((Enabled) && ((!Assigned(ParamValues)) || (ParamValues.length == 0))) {
return;
}
var Filter;
var ValuesExpressions;
var Param;
var ParamExpression;
for (var i = 0; i < Filters.Count; i++) {
Filter = Filters.Items(i);
if ((Filter.Code == FilterCode) && (Filter.FilterType == ftInclude)){
ValuesExpressions = Filter.ValuesExpressions;
DeleteParametersByValueExpressions(Query.Parameters, ValuesExpressions);
ValuesExpressions.Clear();
Filter.IsEnabled = Enabled;
if (!Enabled) {
return;
}
for (var j in ParamValues) {
Param = Query.Parameters.CreateItem();
Param.Name = GenParamName(Query.Parameters);
Param.Value = ParamValues[j];
if (DataType == null) {
DataType = sdtUnicodeString;
}
Param.DataType = DataType;
Query.Parameters.Add(Param);
ParamExpression =
ValuesExpressions.CreateParamFilterExpression();
ValuesExpressions.Add(ParamExpression);
ParamExpression.Code = Connector.GenGUID();
ParamExpression.Parameter = Param;
}
}
}
}
[/javascript]
Эту функцию я не трогал. Она оригинальная.
CRM X25 3.0.4.112, Firebird 2.0
Честно говоря как её отладить я плохо представляю, но придется попробовать...

По вопросу отладки можно почитать тут: http://community.terrasoft.ua/node/1830
Попытаюсь воспроизвести ситуацию, позднее сообщу о результатах.

debugger;
показал, что ApplyQueryIncludeFilter вообще ничего не создаёт.
вставил запись в лог:
[javascript]
...
for (var i = 0; i < Filters.Count; i++) {
Filter = Filters.Items(i);
Log.Write(1, Filter.Code);
if ((Filter.Code == FilterCode) && (Filter.FilterType == ftInclude)){
...
[/javascript]
И получил странную запись
[javascript]
[08.10.03 11.16.30.634] (W) FiltersBuilderOriginalFilters
[08.10.03 11.16.30.634] (W) FiltersBuilderFilters
[/javascript]
Почему так получается не смог понять... Придется отложить до вечера.

Моя ошибка была в том что я не понимал сути возращаемого:
[javascript]
var Select = GetSelectQueryPrimarySelect(Dataset.SelectQuery);
var Filters = Select.Filters;
[/javascript]
Временное решение:
[javascript]
function ApplyQueryIncludeFilter2(Query, Filters, FilterCode, ParamValues, Enabled,
DataType) {
if ((Enabled) && ((!Assigned(ParamValues)) || (ParamValues.length == 0))) {
return;
}
var Filter;
var ValuesExpressions;
var Param;
var ParamExpression;
Filter = Filters;
Log.Write(1, Filter.Code);
if ((Filter.Code == FilterCode) && (Filter.FilterType == ftInclude)){
ValuesExpressions = Filter.ValuesExpressions;
DeleteParametersByValueExpressions(Query.Parameters, ValuesExpressions);
ValuesExpressions.Clear();
Filter.IsEnabled = Enabled;
if (!Enabled) {
return;
}
for (var j in ParamValues) {
Param = Query.Parameters.CreateItem();
Param.Name = GenParamName(Query.Parameters);
Param.Value = ParamValues[j];
if (DataType == null) {
DataType = sdtUnicodeString;
}
Param.DataType = DataType;
Query.Parameters.Add(Param);
ParamExpression =
ValuesExpressions.CreateParamFilterExpression();
ValuesExpressions.Add(ParamExpression);
ParamExpression.Code = Connector.GenGUID();
ParamExpression.Parameter = Param;
}
}
}

function ApplyDatasetIncludeFilter(Dataset, FilterCode, ParamValues, Enabled, DataType) {
var Select = GetSelectQueryPrimarySelect(Dataset.SelectQuery);
var Filters = Select.Filters;
// EnableFilter(Filters, FilterCode, Enabled);
ApplyDatasetIncludeFilterFor(Filters, Dataset, FilterCode, ParamValues, Enabled, DataType);
// Log.Write(1, Connector.DBEngine.GetSelectQuerySQLText(Dataset.SelectQuery));
}

function ApplyDatasetIncludeFilterFor(Filters, Dataset, FilterCode, ParamValues, Enabled, DataType) {
var Result = false;
if (Filters.Code == FilterCode) {
ApplyQueryIncludeFilter2(Dataset.SelectQuery, Filters, FilterCode,
ParamValues, Enabled, DataType);
return true;
}
if (Filters.FilterType == ftFilters) {
for (var i = 0; (i < Filters.Count) && (!Result); i++) {
Result = ApplyDatasetIncludeFilterFor(Filters.Items(i), Dataset, FilterCode, ParamValues, Enabled, DataType);
}
if (Result && Enabled) {
Filters.IsEnabled = true;
}
}
}
[/javascript]

Наблюдаемая ситуация вызвана тем, что построитель фильтров создает свое дерево фильтров в запросе набора данных раздела.
В целом, Ваше решение вполне пригодно. Желаю успехов!

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