Добрый день, Как можно получить данные которые попадают в определенную динамическую группу из базы и в самом CRM-е( по скрипту, если сам этот раздел не был открыт) ?

Спасибо

Нравится

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

Что касается выборке на уровне базы данных, то это не возможно, так как реализация фильтра описана в скриптах, в саму базу данных передается информация в таком примерно виде :

0x3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D225554462D38223F3E0A3C46696C746572734275696C646572526F6F744E6F646520547970653D2246696C746572734275696C6465724974656D73223E0A20203C4974656D20547970653D224C6F6F6B757046696C746572734275696C6465724974656D2220446174614669656C644E616D653D22436F6E74616374547970654944223E0A202020203C4974656D2056616C75653D227B34374342433642422D443734452D343837322D413438382D3735434330313132323133367D222F3E0A202020203C446973706C617946696C656456616C7565733E0A2020202020203C4974656D2056616C75653D22D0A1D0BED182D180D183D0B4D0BDD0B8D0BA20D092D0B0D188D0B5D0B920D0BAD0BED0BCD0BFD0B0D0BDD0B8D0B822205549443D224533414645443245313346393439423342333737443836424332333530443443222F3E0A202020203C2F446973706C617946696C656456616C7565733E0A20203C2F4974656D3E0A3C2F46696C746572734275696C646572526F6F744E6F64653E0A

Как Вы сами понимаете, оперировать этими данными нет возможности, единственным вариантом , используя запросы, есть вариант используя стандартную конструкцию select ......join... where....

Если использовать конфигурацию самой CRM системы, то это может иметь примерно вот такой вид:

string serializedString = string.Empty;
var FolderId = " Folder Guid";
var schemaName  = "Activity";
// Получаем строку из базы по идентификатору группы
var manager = UserConnection.GetSchemaManager("EntitySchemaManager") as Terrasoft.Core.Entities.EntitySchemaManager;
var entitySchema = manager.GetInstanceByName(schemaName);
Entity entity = entitySchema.CreateEntity(UserConnection);
var valueColumn = entitySchema.Columns.GetByColumnValueName ("SearchData");
if (entity.FetchFromDB(entitySchema.GetPrimaryColumnName(), FolderId)) {
                using (MemoryStream stream = entity.GetStreamValue(valueColumn.ColumnValueName)){
                               if (stream != null) {
                                               stream.Position = 0;
                                               serializedString = Terrasoft.Common.StreamUtilities.GetStreamContent(stream);
                               } else {
                                               serializedString = String.Empty;
                               }
                stream.Flush();
                }
}
//Если ничего не нашел очищаем текущие фильтры
if (string.IsNullOrEmpty(serializedString)) {
                if (string.IsNullOrEmpty(FilterName)) {
                               FilterName = "FilterEdit";
                }
                var oldFilters = dataSource.CurrentStructure.Filters.FindByName(FilterName) as DataSourceFilterCollection;
                if (oldFilters != null) {
                               oldFilters.Clear();
                }
                return;
}
//Конвертируем строку в фильтры
var jsonConverter = new DataSourceFiltersJsonConverter(UserConnection, dataSource){
                                                                                                              PreventRegisteringClientScript = true
                                                                                              };
var filters = JsonConvert.DeserializeObject<DataSourceFilterCollection>(
                                                                                              serializedString, jsonConverter);
 
//Загружаем фильтры для текущего датасорса, можно использовать и в запросе
if (filters != null) {
                var existingFilterCollection = dataSource.CurrentStructure.Filters.FindByName(filters.Name) as DataSourceFilterCollection;
                if (existingFilterCollection != null){
                               existingFilterCollection.Clear();
                               var filtersCollection = filters as DataSourceFilterCollection;
                               foreach (var filterItem in filtersCollection) {
                                               existingFilterCollection.Add(filterItem);
                               }
                               existingFilterCollection.LogicalOperation = filters.LogicalOperation;
                               existingFilterCollection.IsEnabled = filters.IsEnabled;
                               existingFilterCollection.IsNot = filters.IsNot;
                }
                else {
                               dataSource.CurrentStructure.Filters.Add(filters);
                }
}

Возможно, были допущены некоторые опечаточки, прошу отнестись снисходительно :)

С уважением Сергей :)

Теоретически решить задачу можно.
Самый простой вариант:
Доработать конфигурацию и БД. В таблице рядом с полем, где храниться фильтр, добавить текстовую колонку и писать sql текст фильтра. Его можно будет получить методами на уровне приложения. Для этого у запросов есть методы для получения текста запроса сразу со значением параметров. Но тут есть нюанс с системными переменными - такими как текущий пользователь и т.п. На уровне приложения их можно узнать из текущей сессии, но на уровне sql сервера - нет такой информации.
Смотрите из SDK:
BuildParametersAsValue
GetSqlText

Вариант сложный:
Написать CLR хранимую процедуру, которая используя наши .net сборки, сможет получить текст фильтра на уровне sql севера. В таком случае необходимо будет постоянно обновлять сборки на sql сервере в случае их обновлений для приложения (сайта). Так же станет вопрос с параметрами и системными переменными.

Добрый день.
Скажите на одном примере запроса: как получить все-таки это поле searchdata?
Либо где посмотреть в коде?
Спасибо!

Кирилл, Выше же есть пример, где получаем SerachData, и на основании его пытаемся воссоздать фильтр EntitySchemaQuery:

var valueColumn = entitySchema.Columns.GetByColumnValueName ("SearchData");

Дмитрий, я имел в виду запрос SQL.

"Sergey Karpenko" написал:Что касается выборке на уровне базы данных, то это не возможно, так как реализация фильтра описана в скриптах, в саму базу данных передается информация в таком примерно виде :

0x3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D225554462D38223F3E0A3C46696C746572734275696C646572526F6F744E6F646520547970653D2246696C746572734275696C6465724974656D73223E0A20203C4974656D20547970653D224C6F6F6B757046696C746572734275696C6465724974656D2220446174614669656C644E616D653D22436F6E74616374547970654944223E0A202020203C4974656D2056616C75653D227B34374342433642422D443734452D343837322D413438382D3735434330313132323133367D222F3E0A202020203C446973706C617946696C656456616C7565733E0A2020202020203C4974656D2056616C75653D22D0A1D0BED182D180D183D0B4D0BDD0B8D0BA20D092D0B0D188D0B5D0B920D0BAD0BED0BCD0BFD0B0D0BDD0B8D0B822205549443D224533414645443245313346393439423342333737443836424332333530443443222F3E0A202020203C2F446973706C617946696C656456616C7565733E0A20203C2F4974656D3E0A3C2F46696C746572734275696C646572526F6F744E6F64653E0A

Как Вы сами понимаете, оперировать этими данными нет возможности, единственным вариантом , используя запросы, есть вариант используя стандартную конструкцию select ......join... where....

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

Добрый день.
Подскажите пожалуйста, где можно посмотреть как создать запрос SelectQuery программно? Особенно интересует полностью программное создание join-ов по нескольким полям.

TerrasoftCRM 3.3.2
Спасибо.

Нравится

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

Здравствуйте, Петр.

Динамически запрос SelectQuery создается приблизительно следующим образом:

var sq = CreateSelectQuery("Common\\" , 'sq_MySelect');
var FromTable = Services.GetNewItemByUSI('tbl_MyTable');
var Select = CreateSelectQuerySelect(sq, FromTable, 'MySelect');
var Join = CreateJoin(Select, LeftField, RightField, ParentJoin);
Join.JoinType = 0;
/*
jtInner = 0x00000000;
jtLeftOuter = 0x00000001;
jtRightOuter = 0x00000002;
jtFullOuter = 0x00000003;
*/
AddColumn(Select, FromTable.Fields('ID'));
AddColumn(Select, FromTable.Fields('Namus'));

Ознакомиться с программным создание join'ов по нескольким полям можно по ссылке: http://www.community.terrasoft.ua/blogs/5494

Спасибо, Дмитрий, очень помогло.

И еще вопрос. У меня на одном экземпляре MS SQL Server работаю две базы: Terrasoft(TS_Original) и база от другой системы (Warehouse). Есть ли возможность из скрипта базы TS_Original делать запросы на вставку и удаление в базу Warehouse?

Здравствуйте Петр!

Такая возможность существует. Вам нужно создать ADOCommand:

добавление компонента происходит (как и для других сервисов)при щелчке правой кнопкой мыши и выборе его из списка.
Компоненту присваивается осмысленное название, например adc_ExportData.
В окне редактирования сервиса есть такие значения, как Строка соединения(можно создать строку соединения без использования существующих
соединений, созданных в компонентах ADOConnection) и Соединение(можно выбрать созданное ранее посредством сервиса ADOConnection соединение).
В поле Текс SQL прописывается команда, например exec ExportData :GroupID, :GroupID - параметр, добавленный в список параметров сервиса.
В скрипте

//получение сервиса
var Command = GetSingleItemByCode('adc_ExportData');
//где 'adc_ExportData' - название сервиса ADOCommand
// установка параметров
SetParameterValue(Command.Parameters, 'GroupID', GroupID);
//запуск на исполнение
Command.Execute();

Подробнее с детальной инструкцией и примерами, Вы можете ознакомиться по ссылке:
http://www.community.terrasoft.ua/forum/topic/2576

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