Добрый день всем!
Свой первый блог решил посвятить задаче поиска дубликатов не по полному совпадению, а по вхождению (с помощью оператора Like). Возможно, кому-то пригодится.
Итак. 1. Начинаем с создания булевого системного параметра "FindDuplicatesWithLike" в клиентском приложении. По умолчанию оставляем его в значении false (стандартный поиск), если же он равен true - будем вызывать функции для поиска по вхождению.
2. В скрипте scr_SubjectDuplicates создаём функцию, аналогичную AddDetailFilter. Её предназначение - формирование условия фильтрации для поиска дублей выделенной записи по полю DataFieldName (используя like):
function AddDetailFilterLike(Select, Dataset, DataFieldName) {
var DataField = Dataset.DataFields.ItemsByName(DataFieldName);
var Filters = Select.Filters;
var CompareFilter = AddLikeFieldFilter(Select, DataFieldName, DataFieldName,
ltContain, Filters);
}
3. В этом же скрипте изменяем функцию UpdateSubjectDataset - добавляем проверку системного параметра:
function UpdateSubjectDataset() {
var SubjectDataset = SubjectDuplicates.SubjectDataset;
var SelectQuery = SubjectDataset.SelectQuery;
var Select = SelectQuery.Items(0);
Select.Filters.Clear();
Select.Filters.ParentParametriticQuery.Parameters.Clear();
var DataFieldNames = SubjectDuplicates.DataFieldNames;
for(var i = 0; i DataFieldNames.length; i++) {
var DataFieldName = DataFieldNames[i];
var FindDuplicatesLikeParameter =
GetSystemParameterValueEx('FindDuplicatesWithLike', true);
if (FindDuplicatesLikeParameter) {
AddDetailFilterLike(Select, SubjectDataset, DataFieldName);
} else {
AddDetailFilter(Select, SubjectDataset, DataFieldName);
}
}
}
4. С этим скриптом закончили. Все остальные изменения - в скрипте scr_DuplicatesUtils. Итак, для начала создаём функции для формирования запроса основного реестра. Одна из них формирует колонку подзапроса для подсчёта количества дублей, а вторая - для формирования условия фильтрации. Их создаём по аналогии с функциями CreateCountSelectExpression и AddCountCompareFilter:
function CreateCountSelectColumn(DuplicatesProperties, Filters, Columns,
CheckFieldNames) {
var SelectFromTable =
Services.GetSingleItemByUSI(DuplicatesProperties.TableName);
var SelectFromTableAlias = SelectFromTable.SQLName + 'Duble';
var SelectColumn = CreateSubselectColumn(Columns);
SelectColumn.ColumnAlias = DuplicatesCode;
Columns.Add(SelectColumn);
var SubSelectQuery = SelectColumn.ColumnSelectQuery;
var ExpressionSelect = AddSelect(SubSelectQuery, SelectFromTable,
SelectFromTableAlias);
var ExpressionFilters = ExpressionSelect.Filters;
var ParentFromTable = Filters.ParentSelect.FromTable;
var ParentFromTableAlias = Filters.ParentSelect.FromTableAlias;
AddCountCompareFilters(ExpressionFilters, ParentFromTable,
ParentFromTableAlias, SelectFromTable, SelectFromTableAlias,
CheckFieldNames);
var ExpressionColumns = ExpressionSelect.Columns;
var SummaryTableField =
SelectFromTable.Fields.ItemsByName(DuplicatesCode);
AddSummaryColumn(ExpressionColumns, DuplicatesCode,
SummaryTableField, stCount);
return SelectColumn;
}
function AddCountCompareFilterLike(ExpressionFilters, ParentFromTable,
ParentFromTableAlias, SelectFromTable, SelectFromTableAlias,
CheckFieldName) {
var TestField = ParentFromTable.Fields.ItemsByName(CheckFieldName);
var ValueField = SelectFromTable.Fields.ItemsByName(CheckFieldName);
var CompareFilter = ExpressionFilters.CreateLikeFilter();
CompareFilter.Code = GenNewKeyValueFromCollection(ExpressionFilters, 'LikeFilter');
ExpressionFilters.Add(CompareFilter);
CompareFilter.TestExpression = AddFieldExpression(ExpressionFilters,
CompareFilter, TestField, SelectFromTableAlias);
CompareFilter.LikeType = ltContain;
CompareFilter.ValueExpression = AddFieldExpression(ExpressionFilters,
CompareFilter, ValueField, ParentFromTableAlias);
return CompareFilter;
}
5. Наконец, вносим изменения в функции CreateDuplicatesSelectQuery и AddCountCompareFilters - добавляем вызовы наших функций в зависимости от значения системного параметра:
function CreateDuplicatesSelectQuery(DuplicatesProperties, Table, FieldNames) {
var CreatedQuery = Services.CreateItem(SelectQueryCode);
var FromTableAlias = Table.SQLName + '1';
var Select = AddSelect(CreatedQuery, Table, FromTableAlias);
var FieldName;
var GeneralColumn;
for (var i = 0; i FieldNames.length; i++) {
FieldName = FieldNames[i];
GeneralColumn = AddGeneralColumn(Select.Columns,
Table.Fields.ItemsByName(FieldName), FieldName);
GeneralColumn.OrderType = otAsc;
GeneralColumn.OrderPosition = i + 1;
}
var SummaryTableField = Table.Fields.ItemsByName('ID');
var FindDuplicatesLikeParameter =
GetSystemParameterValueEx('FindDuplicatesWithLike', true);
if (FindDuplicatesLikeParameter) {
var SummaryColumn = CreateCountSelectColumn(DuplicatesProperties,
Select.Filters, Select.Columns, FieldNames);
} else {
var SummaryColumn = AddSummaryColumn(Select.Columns, DuplicatesCode,
SummaryTableField, stCount);
}
SummaryColumn.OrderType = otDesc;
SummaryColumn.OrderPosition = 0;
AddDuplicateFilters(DuplicatesProperties, Select, FieldNames);
return CreatedQuery;
}
function AddCountCompareFilters(ExpressionFilters, ParentFromTable,
ParentFromTableAlias, SelectFromTable, SelectFromTableAlias,
CheckFieldNames) {
var CheckFieldName;
for(var i = 0; i CheckFieldNames.length; i++) {
CheckFieldName = CheckFieldNames[i];
var FindDuplicatesLikeParameter =
GetSystemParameterValueEx('FindDuplicatesWithLike', true);
if (FindDuplicatesLikeParameter) {
AddCountCompareFilterLike(ExpressionFilters, ParentFromTable,
ParentFromTableAlias, SelectFromTable, SelectFromTableAlias,
CheckFieldName);
} else {
AddCountCompareFilter(ExpressionFilters, ParentFromTable,
ParentFromTableAlias, SelectFromTable, SelectFromTableAlias,
CheckFieldName);
}
}
}
Вот и всё.
Доборый день :)
Получил ошибку при выполении:
var FindDuplicatesLikeParameter = GetSystemParameterValueEx('FindDuplicatesWithLike', true);
"Ошибка выполнения метода 'wnd_SubjectDuplicatesOnPrepare'. Предполагается наличие объекта"
Параметр создал через Файл->Системные настройки. И в таблице tbl_SystemSettings он есть.
Подскажите, пожалуйста, в чем может быть проблема?
Версия: 3.1.0.16
Спасибо!
Думаю, какой- то скрипт не подключили. Например, scr_SystemSettings.
Не совсем :).
В версии 3.1.0 необходимо вызывать
var FindDuplicatesLikeParameter = GetSystemParameterValue('FindDuplicatesWithLike', sptBoolean);
вместо
var FindDuplicatesLikeParameter = GetSystemParameterValueEx('FindDuplicatesWithLike', true);
Просто в скрипте scr_SystemSettings раньше не было функции GetSystemParameterValueEx.
Вообще доработка реализовывалась на версии 3.3.1, на более ранних версиях возможны проблемы.
Олег Лабьяк,
разработчик,
3-я линия Службы поддержки Terrasoft.
Олег, могу предложить тему для следующей записи в блоге - "нечеткий поиск" для поиска дублей :smile: Для справочников - мегаактуально.
Сергей, спасибо за предложение! Задача интересная, можно попробовать.
Олег Лабьяк,
разработчик,
3-я линия Службы поддержки Terrasoft.