Доброго дня!
Хочу сделать возможность переноса данных из одного датасета в другой.
В гриде детали первого раздела сделал кнопку, при нажатии на которую открывается окно второго раздела с записями.

var wndContactsGridArea =  Services.GetNewItemByUSI('wnd_OfferingOrderGridArea');
wndContactsGridArea.Prepare();
var Dataset = wndContactsGridArea.ComponentsByName('dlData').Dataset;
RefreshDataset(Dataset);
WndContactsGridArea.ShowModal();

Может кто подсказать как в этом окне сделать импорт из одного раздела в другой? И можно ли вообще так сделать?
Хочется, чтобы пользователям не приходилось дублировать записи в каждом разделе.

Нравится

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

Здравствуйте, Дмитрий!

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

В Вашем случае в вызываемое по кнопке окно нужно передавать Dataset раздела, из котого Вы хотите импортировать данные и ID его записей, тогда в зависимости от этих значений реализовывать копирование нужных записей.

Можно усложнить задачу и вызывать не окно раздела, в который Вы хотите копировать данные, а реализовать своё окно именно под эту задачу, которое может быть похоже, например, на wnd_MultiSelectData.

Вот мне хотелось бы сделать следующую реализацию:
По нажатию на кнопку открывается окно с разделом, в который я хочу передать данные. В этом окне я выбираю нужную запись и после информационного сообщения "Найдено n продуктов, импортировать их?" происходила передача данных

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

Мне нужно переопределить метод GotoNext() датасета, чтобы он выполнял помимо стандартной своей функции еще одно дополнительное действие. Переопределение метода позволит избежать масштабных единообразных изменений в коде.

Есть ли такая возможность в Terrasoft 3.X?

Буду благодарен за примеры.

Нравится

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

Это не оно?

function ds_AccountOnDatasetBeforePositionChange(Dataset) {
	//TODO
}
 
function ds_AccountOnDatasetAfterPositionChange(Dataset) {
	//TODO
}

Или нужно во всех таблицах сразу?

"Зверев Александр" написал:Или нужно во всех таблицах сразу?

Это могут быть разные датасеты, не один какой-то конкретный, а какой попадется в тот момент.
В принципе, можно присвоить свой обработчик на событие AfterPositionChange.

Есть функция SetObjectEventDispatcher.

Пример в конфигурации:

//-------------------------------------
// wnd_MailTemplateLinkGridAreaScript
//-------------------------------------
 
...
 
 
function FillDataset(Dataset) {
...
}
 
 
function DoAdd() {
	var Dataset = MailTemplateLinkGridArea.ColumnsDataset;
	if (!Dataset) {
		Dataset = GetSingleItemByCode('mds_DictionaryTemplate', 
			'wnd_MailTemplateLinkGridAreaScript');
		Dataset.Caption = "Поле для связи сообщения";
		SetObjectEventDispatcher(Self, Dataset, Dataset.Name, 'OnDatasetAfterOpen',
			'FillDataset');
...
}

спасибо, пригодится

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

Понадобилось добавить кнопку "Установить скидку на все продукты в счете" в воркспейс "Продукт" (wnd_OfferingDetailTreeArea) детали раздела "Счета". Решил изучить как обрабатываются события нажатий на другие кнопки воркспейса wnd_OfferingDetailTreeArea. Однако, я не нашёл ни одного привязанного к кнопкам обработчика. Кроме того, оказалось, что в "Невизуальных коммпонентах" к dlData не привязан никакой датасет.
Пожалуйста, объясните, как это всё работает? Где обработчики? Откуда подгружаются данные и куда они выгружаются при работе, если к воркспейсу не привязан датасет?
Где мне впредь искать ответы на данные вопросы? Неужели придётся каждый раз обращаться по таким вопросам на community или в тех. поддержку? Должно же это быть где-то расписано?

Нравится

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

Во-первых, wnd_OfferingsDetailTreeArea.
Обработчики там должны быть, странно. В скрипте wnd_OfferingsDetailTreeAreaScript вижу:

function btnAddRootOnClick(Control) {
	AddRootData();
}
 
function btnAddChildOnClick(Control) {
	AddChildData();
}
 
function btnCopyOnClick(Control) {
	CopyData();
}
 
function btnEditOnClick(Control) {
	EditData();
}

Датасет не привязан, поскольку эта деталь может быть в разных разделах и привязывается программно при открытии раздела.

"Зверев Александр" написал:Датасет не привязан, поскольку эта деталь может быть в разных разделах и привязывается программно при открытии раздела.

Если точнее, Датасет привязывается в скрипте Воркспейса Счетов:

if (pcDetails.ActivePage.Name == pgOfferingsDetail.Name) {
		SetAttribute(wndOfferingsDetail.Window, 'WorkspaceDataset',
			BaseWorkspace.GridDataset)
		SetAttribute(wndOfferingsDetail.Window, 'DateFieldName', 'InvoiceDate');
		SetAttribute(wndOfferingsDetail.Window, 'AccountFieldName', 'CustomerID');
		RefreshCommonDetail(BaseWorkspace, wndOfferingsDetail, 
			'InvoiceID', 'InvoiceID', 'ds_OfferingInInvoice');
}

В RefreshCommonDetail 5-ым параметром передается USI датасета, который хотите в данном случаи привязать.

Действительно, у меня обработчики не были подцеплины только в тестовой базе, видимо раньше когда-то напортачил, теперь подцепил. В действующей - всё ок.

Всем спасибо!

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

Здравствуйте, подскажите, как получить ссылку на интересуемый датасет (в частности, на датасет ds_Invoice)?

Нравится

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

Добрый день!
Можно создать экземпляр датасета:
var DS = Services.GetNewItemByUSI('ds_Invoices');
есть также функция фильтрация датасета, ApplyDataSetFilter, посмотрите примеры в конфигурации воспользовавшись глобальным поиском alt+shift+S

Мне в чате подсказали, что это можно сделать так:
var ContractDataset = Services.GetNewItemByUSI('ds_Invoice');
Однако, при передаче первым параметром СontractDataset в функцию ApplyDatasetFilter() Террасофт ругается на именно на первый параметр.

Общая задача: отфильтровать выборку значений поля

Листинг обработчика поля

function edtContractIDOnPrepareSelectWindow(LookupDataControl) {//обработчик поля "Договор"
    var OrderDataset = dlData.Dataset;
    var InvoiceID = GetFieldValueFromDisabledField(OrderDataset, 'InvoiceID');
    var ContractDataset = Services.GetNewItemByUSI('ds_Invoice');    
    ContractDataset.DisableEvents();
    var IsEnabled = (!IsEmptyValue(InvoiceID));
    ApplyDatasetFilter(ContractDataset, 'InvoiceID', InvoiceID, IsEnabled);	
    ContractDataset.Open();
    ContractDataset.Close();	   
}

:

"Борисов Михаил Евгеньевич" написал:

var Dataset = Services.GetSingleItemByUSI('ds_Invoice');


Не помогло, всё равно - ошибка

Оно ругается, поскольку в sq_Invoice нет фильтра InvoiceID. Вы вообще что хотите получить, отфильтровать договор по значению счёта?

Тогда нужно так:

function edtContractOnPrepareSelectWindow(LookupDataControl) {
        var Dataset = dlData.Dataset;
        var InvoiceID = GetFieldValueFromDisabledField(Dataset, 'InvoiceID');
        var LookupDataset = LookupDataControl.DataField.LookupDataset;
        var IsEnabled = (!IsEmptyValue(InvoiceID));
        ApplyDatasetFilter(LookupDataset, 'InvoiceID', InvoiceID, IsEnabled);
}

А ссылка на ds_Invoice тут не нужна.

Александр, соглашусь, я уже тут подзапутался и действительно, мой скрипт неправильный.
Я пробовал, как Вы говорите. В sq_Contract не было необходимого параметра, поэтому я сначала добавил соответствующие изменения сначала в tbl_Contract (новое поле "Связанный счет"), потом в ds_Contract, а потом добавил параметр InvoiceID в sq_Contract
Однако, работа скрипта типа того, что вы мне написали (в названии "ID" после edtContract пропущено) фильтрует абсолютно все записи.
И связано это с тем, что при создании договора новое поле "InvoiceID" ("Связанный счет") не инициализируется. От счета можно перейти к связанному договору, а обратно - нет. Получается мне сначала нужно реализовать эту обратную связь, чтобы при заполнении в счёте поля "Договор" в самом договоре инициализровалось поле связанный счет? Тогда подскажите как это сделать?

Сначала объясните, что вообще хотите сделать. Добавлять новое поле, если оно не используется, не нужно.

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

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

А смысл тогда вообще фильтровать, если со счётом может быть связан только один договор? Выбор из одного варианта?
Может, лучше просто при выборе счёта автоматически записывать в поле "договор" заявки договор из счёта?

Я не уточнил, нужно дать возможность добавить новый или оставить поле пустым.
Вариант фильтрации устраивает, но он не работает

В таком случае, можно так:

function edtContractIDOnPrepareSelectWindow(LookupDataControl) {
        var Dataset = dlData.Dataset;
        var InvoiceID = GetFieldValueFromDisabledField(Dataset, 'InvoiceID');
        var ContractID = GetDatasetFieldValueByID('ds_Invoice', InvoiceID, 'ContractID');//вместо кучи кода с Services.GetNewItemByUSI
        var LookupDataset = LookupDataControl.DataField.LookupDataset;
        var IsEnabled = (!IsEmptyValue(ContractID));
        ApplyDatasetFilter(LookupDataset, 'ID', ContractID, IsEnabled);
}

Благодарю, всё получилось!
Займусь разбором написанного Вами кода по SDK.

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

Здравствуйте!
Возникла следующая ошибка:

есть таблица tbl_Brief с полями WCCitiesT и WCCitiesText с типом строкоа юникод (1500) и строка юникод (2500).
есть датасет ds_Brief с полями WCCitiesT и WCCitiesText с типом blob (когда эти поля были типа "строка", данные все равно обрезались).

Есть окно редактирования, в нем Lookup поле, в котором вызывается wnd_MultiSelectData. при нажатии ОК в этом окне происходит следующее:

if ((Sender.Name == 'wnd_MultiSelectData')
                  && (Sender.WindowCaption == "Выбор 'Город'")&& (Message == MSG_OK)) {                                
        CitiesIDString = Sender.Attributes('KeyValues').CommaText;
      Lookup.Text = Sender.Attributes('DisplayFieldValues').CommaText;
        Self.ComponentsByName('dlData').Dataset.Values('WCCitiesText') = Sender.Attributes('DisplayFieldValues').CommaText;
        var t = new String (Sender.Attributes('KeyValues').CommaText);
        Self.ComponentsByName('dlData').Dataset.Values('WCCitiesT') = CitiesIDString
                    }

Потом при нажатии ОК в окне редактирования по профайлеру видно, что добавляется запись с пустыми значениями этих полей (хотя BaseDBEdit.Dataset.Values('WCCitiesT') и BaseDBEdit.Dataset.Values('WCCitiesText') не пустые). При чем только при первом добавлении записи в грид за сеанс. Если потом открыть ту же запись или создать новую, то значения полей добавляются.

в чем может быть проблема?

Нравится

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

Здравствуйте.
Сложно сказать в чем может быть проблема. Не понятно почему у Вас обрезается строка, если конечно у Вас и в таблице в и датасете длина поля типа nvarchar установлена одинаковая (1500 b 2500 соответственно).
Можете предоставить резервную копию БД для анализа проблемы?

Да, длина строк была одинаковая. но сейчас проблема не в этом, а в том, что при первой записи в датасет значения этих полей не сохраняются.

а смотрели события самого датасета? после выделенной строки как раз и срабатывает beforepost датасета (и потом afterpost)

эти события стандартные.

Елена, подозреваю, что Дмитрий имел ввиду, что следует проверить события BeforePost и AfterPost для этого датасета в скрипте самого датасета и в скрипте карточки. Возможно в функциях обработчиках этих событий есть какая либо логика, которая в первый раз (для новой записи) очищает значение этих полей в датасете.

я поняла. Я имела ввиду, что в скрипте датасета нет нестандартных функций на это событие, как и в карточке.

Лена, в таком случае нужно смотреть реализацию.
Без отладки и анализа реализации сложно определить причину. Вложите, пожалуйста, сервисы функциональности либо направьте в службу технической поддержки резервную копию БД.

Оказалось, что если типа поля датасета поменять на строковый вместо blob, то всё сохраняется с перовго раза.

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

Может кто-нибудь пояснить мне разницу между методами получения значения полей данных в датасете:
* Dataset.ValAsGUID('') (ValAsStr, ValAsFloat etc)
* Dataset.Values('')
* Dataset('')

Например, я знаю, что Dataset.Values('') передает null, а ValAs... как правило нет

Нравится

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

ValAsStr - конвертирует к строке
ValAsFloat - конвертирует к дробному числу
ValAsGUID - конвертирует к GUID (строка)
Если хранится null в поле, тогда он вернет либо пустую строку либо 0.

Dataset('') тоже самое что и Dataset.Values

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

Здравствуйте. Заранее извиняюсь, если такая тема уже поднималась на форуме. При заполнении карточки редактирования добавления нового контрагента необходимо, чтобыбы в поле Страна уже стояло определенное значение (в моем случае Беларусь). Подскажите, как это сделать.

Нравится

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

Если у вас поле не предполагает наличие пустой строки, на OnPrepare можно поставить:
if (dlData.Dataset('Country') == null) { //Пустое поле, при создании, оно естественно пустое
dlData.Dataset('Country') = "Беларусь";
}

На OnPrepare окна редактирования контрагента? Если да, то не получается.

В сервисе scr_AccountEdit:

в функцию wnd_AccountEditOnPrepare добавьте

var Dataset = dlData.Dataset;
if (Dataset.State == dstInsert){
Dataset.Values('CountryID') = '{8DE1DE57-C698-4155-B191-38A36F4A7C8D}';
}

'{8DE1DE57-C698-4155-B191-38A36F4A7C8D}' - идентификатор страны

"Sergey Karpenko" написал:

В сервисе scr_AccountEdit:

в функцию wnd_AccountEditOnPrepare добавьте

var Dataset = dlData.Dataset;
if (Dataset.State == dstInsert){
Dataset.Values('CountryID') = '{8DE1DE57-C698-4155-B191-38A36F4A7C8D}';
}
'{8DE1DE57-C698-4155-B191-38A36F4A7C8D}' - идентификатор страны


Попробовал. Теперь, конечно, по умолчанию стоит действительно Беларусь, но при попытке выбрать другую страну из списка стран список стран вообще пуст, кроме Беларуси. При попытке добавить новую страну террасофт ведет себя неадекватно.

И так, давайте последовательно, конкретно по Вашему примеру (выбираем Беларусь)

1) заходим в sq_Country

2) определяем необходимый ID страны

3) переходим в сервис scr_AccountEdit:
в функцию wnd_AccountEditOnPrepare
вносим изменения

if (dlData.Dataset.State == dstInsert){ 
	if (IsEmptyValue(dlData.Dataset.Values('CountryID'))) {
		edtCountry.UnprepareDropDownList();
	}
	dlData.Dataset.Values('CountryID') = '{E66E4C45-6AC0-4FCD-BD15-14C4642B70E5}';
}

наслаждаемся результатом!
Приятной работы с Террасофт!

"Sergey Karpenko" написал:

И так, давайте последовательно, конкретно по Вашему примеру (выбираем Беларусь)

1) заходим в sq_Country

2) определяем необходимый ID страны

3) переходим в сервис scr_AccountEdit:
в функцию wnd_AccountEditOnPrepare
вносим изменения

if (dlData.Dataset.State == dstInsert){
        if (IsEmptyValue(dlData.Dataset.Values('CountryID'))) {
                edtCountry.UnprepareDropDownList();
        }
        dlData.Dataset.Values('CountryID') = '{E66E4C45-6AC0-4FCD-BD15-14C4642B70E5}';
}

наслаждаемся результатом!
Приятной работы с Террасофт!


А теперь после Вашего кода попробуйте войти в клиент и заполнить карточку контрагента, указав другую страну, чем та, что стоит по умолчанию. У меня почему-то список других стран после сего кода пропал.

Алексей!
при выборе страны, подставляется и территория, по ней идет фильтр.

Уберите территорию, все будет работать.

Все. Спасибо всем большое. Разобрался.

Поле территория в моем окне редактирования скрыто. Соответственно сбросить значение фильтра мне из окна редактирования нет возможности. Как можно этот фильтр обойти?

приведите функцию function ProcessAddressFieldChanged(DataField) в сервисе scr_AddressUtils

к такому виду :

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

Добрый день.
Есть датасет "Расписание", в котором имеется "ContactID" менеджер, "Date" дата и "StatusID" Статус (нужна, не нужна встреча).
Вот мучаюсь как же открыть датасет с любого места и получить оттуда любого менеджера (первого) которому нужна встреча на конкретное число. И в дальнейшем поменять его статус.

Нравится

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

Константин, обратиться к датасету из любого скрипта можно таким образом:

var Dataset = Services.GetNewItemByUSI('ds_xxx');

Чтобы получить требуемые данные (например, менеджера, которому нужна встреча на конкретное число) датасет следует отфильтровать.

ApplyDatasetFilter(Dataset, FilterName, ParamValue, true);

Затем открыть и считать данные:

Dataset.Open();
var ContactID = Dataset.Values('ContactID');

Чтобы изменить данные, необходимо использовать такой код:

Dataset.Edit();
Dataset.Values('StatusID') = StatusID;
Dataset.Post();

Оказывается все правильно делал. Дело было в фильтрации, ошибся в названии поля (OpportunityTypeID и OpportunityID), пытался фильтровать по другому полю :smile:
Спасибо за подробное объяснение. Тему закрываем.

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

Если для двух полей в датасете с одинаковым заголовком (в моем случае «контрагент») установить свойство Display Field (поле для отображения), то при обращении к датасету (в моем случае, использовании справочника) будет происходить свал с текстом:

1

Поэтому одинаковых заголовков следует избегать

1

Нравится

Поделиться

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

Можно как то получить данные с таблицы, без датасета. Возможно запросом?

Нравится

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

Возможно, но что Вы предполагаете делать ними дальше?

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

В dataset можно "вытащить" эту дату и получать ее с помощью функции GetDatasetFieldValueByID либо GetDatasetFieldValueFromDatasetByUSI, обе функции находятся в скрипте scr_DB.

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