В sq_ сервисе есть возможность установить свойство "Использовать представление без фильтра по правам" (на скриншоте). Но это свойство неактивно. Как сделать его активным?

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

Нравится

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

сначала поставьте галочку в целевой таблице
**как работает не знаю)

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

Т.е. есть определенный sq_запрос
С помощью фильтра вывожу Конрагентов:

        var selectQuery = GetSingleItemByCode('sq_Search');
	ApplySelectQueryFilter(selectQuery, 'ID', AccountID, true);
	var dataset = selectQuery.Open();

У Администраторов все выводится как надо, но для обычных пользователей не выводятся Контрагенты к которым у них нет доступа (отсутствуют Группа или сам пользователь в Детали Доступ грида Контрагенты). И этих контрагентов в данном запросе-фильтре нужно показать для обычных пользователей.
Судя по профайлеру в sq_запросе sq_Search для обычных пользователей вместо tbl_Account выводится vw_Account. А для vw_ уже применяются права доступа.
Вот как обойти эти права доступа для обычных пользователей только для конкретного данного запроса (не применяя галки)?
Примерно как

Dataset.DisableEvents();
Dataset.EnableEvents();

только для прав доступа.

[Шепотом] Рискну предложить создать вьюшку, дать на нее всем права и пользоваться на здоровье...

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

Подскажите как в одном ShowWarningDialog вывести значения массива списком?
К примеру в таким случае:

        var Arr = new Array();
        var i = 0;
        Dataset.GoToFirst();           
        while (!Dataset.IsEOF) {
        var AccountName = DatasetPhone.Values('AccountName');
        var ContactName = DatasetPhone.Values('ContactName');
       
                Arr[i] = i + ' ' + AccountName;
                i++;
        ShowWarningDialog(i + '. Клиент:' + AccountName + ';
        Dataset.GoToNext();
        }

При этом, чтобы окно ShowWarningDialog открылось один раз со всем списком сразу, а не открывалось по одному разу с одним клиентом.

Нравится

2 комментария
var i = 1;
var AccountList = '';
Dataset.GoToFirst();            
while (!Dataset.IsEOF) {
        var AccountName = Dataset.Values('AccountName');
                AccountList = AccountList +  i + '. Клиент: ' + AccountName +'\r\n';
                i++;
        Dataset.GoToNext();
}
ShowWarningDialog(AccountList);

что то вроде этого подойдет?
ps поправил немного

Да, спасибо, то что надо.

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

Подскажите, как передать значение из одного wnd_Window1 в edtEdit.Value в другом окне wnd_Window2 при отсутствии Dataset.

В случае с передачей в Dataset делаю так:

var Attributes = GetNewDictionary();
Attributes("RecordID")            = "{00000000-0000-0000-0000-000000000000}";
Attributes("IsNew")               = true;
Attributes("IsCopy")              = false;
var DefaultValues = GetNewDictionary();
DefaultValues("Source1")       = Control.ParentWindow.Attributes("Source");
ShowEditWindowEx("wnd_Window2", Attributes, DefaultValues);

Нужное значение Control.ParentWindow.Attributes("Source"); передается, т.е. при открытии wnd_Window2 мы видим в поле Source1 наше значение.

Но, как в этом же случае передать значение в edtEdit.Value при отсутствии Dataset?

Нравится

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

Attributes("Source1") = Control.ParentWindow.Attributes("Source");

Это будет передача атрибута для окна.
Потом на OnPrepare нового окна ловите его атрибут и пишите значение атрибута в контрол в скрипте

var Source1Value = Self.GetAttribute("Source1");
edtEdit.Value = Source1Value;

Здравствуйте, Alex GF!

Если я правильно понял, то edtEdit - это контрол без привязки к датасету.

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

"Александр Кудряшов" написал:

Attributes("Source1") = Control.ParentWindow.Attributes("Source");

Это будет передача атрибута для окна.

Потом на OnPrepare нового окна ловите его атрибут и пишите значение атрибута в контрол в скрипте

var Source1Value = Self.GetAttribute("Source1");

edtEdit.Value = Source1Value;


Во втором окне не может определить атрибут:
здесь :

var Source1Value = Self.GetAttribute("Source1");

пишет:
Объект не поддерживает это свойство или метод.

UPD:
А вот таким образом:

var Source1Value = GetAttribute(Self, 'Source1');

Атрибут определился.

Да, либо так:

GetAttribute(Self, "Source1");

либо так

Self.Attributes("Source1");

"Alex GF" написал:Атрибут определился.

Попутал функции, что ж делать.. смысл тот же... живу одновременно в мире кодов трех поколений TS :)

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

В программе произошел сбой - тип контрагентов "Клиенты" переименовался в "подряд". Хочу это исправить, с помощью Админ части Террасофта и возможно других программных продуктов.
Подскажите в каком разделе хранятся все типы контрагентов в админ части террасофта, а также как изменить наименование доступных типов контрагентов. БД - Файерберд. Клиент - Террасофт 3.31.182

Нравится

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

Так переименуйте снова через справочник, меню: Файл-Справочники-Контрагенты-Типы контрагентов.
Находите там "подряд" и переименовываете обратно в "Клиенты".

"Александр Кудряшов" написал:

Так переименуйте снова через справочник, меню: Файл-Справочники-Контрагенты-Типы контрагентов.

Находите там "подряд" и переименовываете обратно в "Клиенты".

Спасибо, Вы Гений!

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

Добрый день!

Подскажите, пожалуйста, как в функции SaveChanges, а точнее в BaseDBEdit.Dataset.Post() определяется набор полей которые надо обновить? Почему-то измененное поле сохраняется не всегда...

Заранее благодарен.

Нравится

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

"AlexLS" написал:как...определяется набор полей которые надо обновить

никак. Поля, которые Enabled в датасете, сохраняются в БД. Конечно, если поля корректно настроены и для них нормально формируется элемент в selectQuery. Например, если поле получается подзапросом, его изменения просто так не сохранятся.

см также http://www.community.terrasoft.ru/blogs/8933

ПС.

"AlexLS" написал:Почему-то измененное поле сохраняется не всегда...

когда сохраняется, а когда - нет?
А другие поля сохраняются, когда это не сохраняется?
Проверьте профайлером, идет ли у вас апдейт таблицы в тех случаях, когда не сохраняется.

"AlexLS" написал:Почему-то измененное поле сохраняется не всегда...

Александр, это же подход менеджера, но не разработчика :)
Профайлер в руки и упорным анализом логов познаем закономерность.
Кстати эффект "не сохраняется" может быть из-за криво написанных обработчиков событий на датасете или карточке - типа смены значений полей при изменении других... смены не видно глазами, а она фоном происходит в датасете, ну и при сохранении уже в таблицы попадает

"Андросов Дмитрий" написал:когда сохраняется, а когда - нет?

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

function SaveChanges(BaseDBEdit, Window) {
...
var PostResult = BaseDBEdit.Dataset.Post();
...

, значения следующие:

Dataset.DataFields('PhoneNumber').IsReadOnly = false;
Dataset.DataFields('PhoneNumber').ValueIsChanged = true;
Dataset.DataFields('PhoneNumber').IsEnabled = true;
Dataset.SelectQuery.Columns.ItemsByAlias('PhoneNumber').IsEnabled = true;

Что-то еще забыл указать? (да, сразу после поста значения НЕ изменились!)

"Андросов Дмитрий" написал:Проверьте профайлером, идет ли у вас апдейт таблицы в тех случаях, когда не сохраняется.

остальные поля сохраняются. Профайлер показывает то что и подразумевается, исключая одно несчастное поле, которое, почему-то игнорится при апдейте!

Проверьте в датасете - быть может у вас Updatequery не генерируется автоматом?

"Олейник Дмитрий" написал:Проверьте в датасете - быть может у вас Updatequery не генерируется автоматом?

Наверно тогда бы другие поля не сохранялись? А так обновляются все поля кроме указанного текстового поля. Ну в датасете все прописано нормально.

Добрый день!

Прошу уточнить, какое у Вас состояние датасета перед "постом":

BaseDBEdit.Dataset.State

Также, посмотрите, какой UpdateQuery у Вас генерируется перед изменением значения, а какой - после.
Также, посмотрите запрос в профайлере SQL.

"Безродный Андрей" написал:Прошу уточнить, какое у Вас состояние датасета перед "постом":

Состояние где "надёжнее" проверить? В "OnDatasetBeforePost" датасета или в скрипте карточки в "dlDataOnDatasetBeforePost" (аналогичный вопрос с after)?

"Безродный Андрей" написал:Прошу уточнить, какое у Вас состояние датасета перед "постом":

BaseDBEdit.Dataset.State

В ProcessBaseDBEditOKOnClick -> SaveChangesWithCheck -> SaveChanges

	var PostResult = BaseDBEdit.Dataset.Post();

смотрю:
перед: BaseDBEdit.Dataset.State 2 Number
после: BaseDBEdit.Dataset.State 1 Number

Запрос:

exec sp_executesql N'UPDATE [dbo].[vw_SCall]
	SET [ModifiedOn] = getdate(),
	[ModifiedByID] = ''{9149E4AB-B8E2-491A-A2B1-AA344021DAF8}'',
	[Description] = @P1
WHERE([vw_SCall].[ID] = @P2)',N'@P1 varbinary(8000),@P2 uniqueidentifier',NULL,'835BBD40-EAE4-4139-8466-93A00156C624'

"Безродный Андрей" написал:какой UpdateQuery у Вас генерируется перед изменением значения

BaseDBEdit.Dataset.UpdateQuery.SQLText
UPDATE [dbo].[vw_SCall]
	SET [ModifiedOn] = NULL,
	[ModifiedByID] = NULL
WHERE([vw_SCall].[ID] = :ID)

не смотря на то что:

Dataset.DataFields('PhoneNumber').ValueIsChanged = true
BaseDBEdit.Dataset.DataFields('PhoneNumber').ValueIsChanged = true

Под пользователем ограниченным выполняем изменение? Судя по wv_SCall

Советую посмотреть триггер tr_vw_SCall_IU (где-то так должен называться) на этой вьюшке, который отвечает за update непосредственно таблицы, по результату update вьюхи. Там с этим полем PhoneNumber все в порядке - может пропущено оно где в запросах?

"Александр Кудряшов" написал:посмотреть триггер tr_vw_SCall_IU

посмотрел [dbo].[tr_vw_SCall_IU]
есть строка  [P].[PhoneNumber] = [I].[PhoneNumber],  
у меня мысли были что из-за того что поле где-то принимает  IsReadOnly = true (а я меняю это значение если вставка необходима), может как-то влияет на строящийся запрос вставки, но как это подтвердить не знаю и как поправить тоже не понимаю...

а галочка в selectQuery под названием "Всегда выбирать в запросе" стоит? :cool:

"Андросов Дмитрий" написал:

а галочка в selectQuery под названием "Всегда выбирать в запросе" стоит? :cool:


А зачем она, если поле в SELECT'е выбрано? Или тут тоже есть "секрет"?

Если она не стоит и поле нигде не отображается, оно не попадает в запрос. По аналогии можно предположить (я не знаю как на самом деле), что если поле при создании экземпляра датасета имеет свойство Только на чтение, оно не попадает в автоматически формируемый UpdateQuery. Т.к. UpdateQuery формируется на основе SelectQuery, можно предположить, что эта галочка добавит поле в апдейт, игнорируя признак Только на чтение. Попробуйте)
Правильно ли я понял, что в самом датасете (сервисе) у вас стоит свойство Только на чтение для этого поля, а потом в скрипте вы его меняете? Если так, то попробуйте установить его в False, а потом в скрипте менять по необходимости.

А я бы предложил вообще без всяких хитрых изменений попробовать в совершенно отвлеченном месте получить экземпляр этого датасета, отключить ему эвенты и попробовать сделать Open(), Edit(), потом поменять значение поля нужного и Post(). Потом посмотреть все ли поменялось. Если ок, искать причины в том месте, где возникает проблема - карточка, события на датасете и т.д

"Андросов Дмитрий" написал:Правильно ли я понял, что в самом датасете (сервисе) у вас стоит свойство Только на чтение для этого поля, а потом в скрипте вы его меняете?

Дмитрий, спасибо! В датасете галка не стоит, а устанавливается в true на OnPrepare, затем на кнопке OK на всякий случай меняю это свойство на false.

"Александр Кудряшов" написал:Потом посмотреть все ли поменялось

Александр, спасибо! Видимо так и придется пробовать!

Итак, если кому-то интересно: :biggrin:

на  OnDatasetBeforeEdit нельзя вешать обновление данных

"AlexLS" написал:на  OnDatasetBeforeEdit нельзя вешать обновление данных

конечно, т.к. это событие которое срабатывает перед переводом датасета в состояние редактирования (Dataset.Edit())

"Андросов Дмитрий" написал:конечно, т.к. это событие которое срабатывает перед переводом датасета в состояние редактирования (Dataset.Edit())

Дмитрий, если б Вы это "конечно" сказали тут было бы круто!!!

"AlexLS" написал:если б

если б вы о OnDatasetBeforeEdit сказали бы раньше, чем тут было бы тоже весьма кстати

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

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

Нравится

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

Как именно вы его открываете и какова вообще задача?

"Андросов Дмитрий" написал:

Как именно вы его открываете и какова вообще задача?

Открываю так:
WindowPrompt = GetSingleItemByCode('wnd_CategoryGiftArea');
WindowPrompt.ShowModal();

Мне нужно отобразить в собственном окне данные справочника.

Такое чувство, что окно базу не подключает.

если ваш реестр унаследован от базового и все остальное настроено правильно, то вам надо просто добавить Prepare() в эту функцию:

WindowPrompt = GetSingleItemByCode('wnd_CategoryGiftArea');
WindowPrompt.Prepare();
WindowPrompt.ShowModal();

"Андросов Дмитрий" написал:если ваш реестр унаследован от базового и все остальное настроено правильно, то вам надо просто добавить Prepare() в эту функцию:

Пробовал, не отображает.
В обработчике этого события нужно, что-то писать?

"Егоров Руслан" написал:В обработчике этого события нужно, что-то писать?

если ваш реестр унаследован от базового и для dlData указан нужный датасет, то достаточно в OnPrepare написать

wnd_BaseGridAreaOnPrepare(Window);

"Андросов Дмитрий" написал:если ваш реестр унаследован от базового

А если нет?

тогда надо проинициализировать все (в т.ч. датасет) самому. Проще унаследовать :wink:

"Андросов Дмитрий" написал:Проще унаследовать

Т.е. указать значение в свойстве TemplateWindowUSI = wnd_BaseGridArea?
А после этого я могу удалить в окне не нужные мне элементы?

лучше использовать вот эту кнопку и, да, потом скрыть то, что не нужно

"Андросов Дмитрий" написал:потом скрыть то, что не нужно

можно только скрыть или удалить тоже можно?

"Егоров Руслан" написал:удалить тоже можно

не выйдет :smile:

"Андросов Дмитрий" написал:Проще унаследовать

Создал окно заново, но данных так и нет((
Где еще капать?

для начала прочитайте
http://www.community.terrasoft.ru/developer/advice/4576
а потом посмотрите, как реализованы существующие реестры

если не поможет, покажите скриншоты настроек окна и его скрипт

"Андросов Дмитрий" написал:для начала прочитайте
http://www.community.terrasoft.ru/developer/advice/4576
а потом посмотрите, как реализованы существующие реестры

если не поможет, покажите скриншоты настроек окна и его скрипт


Делал всё также.


а теперь еще события окна, пожалуйста

ПС. вы знаете о существовании окон выбора из справочника?

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

Открыть свое окно можно следующим образом:

var EditWindowUSI = 'wnd_OpportunityEdit';
var Attributes = GetNewDictionary();
Attributes.Add('RecordID', GUID_NULL);  // если не указываем RecordID, то открывается окно для добавления данных, если указываем, то запись с ID = RecordID открывается для редактирование
var DefaultValues = GetNewDictionary();  // значения по умолчанию
DefaultValues.Add('CustomerID', AccountID); 
ShowEditWindowEx(EditWindowUSI, Attributes, DefaultValues);

"Безродный Андрей" написал:Здравствуйте!

Открыть свое окно можно следующим образом:

Это тоже пробовал. Та же самая ситуация, данных нет.

"Андросов Дмитрий" написал:ПС. вы знаете о существовании окон выбора из справочника?

Где можно про это почитать?

"Андросов Дмитрий" написал:а теперь еще события окна, пожалуйста

Вот:

Сделал через вызов окна "SelectData".
Но мне бы хотелось узнать, как можно подгрузить данные в своё окно?

Сделайте dlData.Dataset.Open() на OnPrepare()

"Олейник Дмитрий" написал:Сделайте dlData.Dataset.Open() на OnPrepare()

Сделал, не подгружает.

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

Прикрепите все используемые Вами сервисы и сообщите точную версию.

Будем воспроизводить.

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

В разделе «Контрагенты» в окне основного реестра записей создать кнопку «Зафиксировать подарки» по нажатию на которую всем контактным лицам контрагента у которых день рожденья в этом месяце будет происходить добавление на деталь «Подарки» новой записи. При этом должно появиться диалоговое окно позволяющее массово для всех записей указать категорию подарка, дата должна быть ровна дате дня рожденья контакта.

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

Нравится

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

1. Добавляете кнопку
2. Добавляете обработчик на кнопку:

3. В обработчике открываете окно выбора с помощью функции ShowSelectDataWindow из scr_WindowUtils (или аналогичных - они там же рядом)
попутно учимся пользоваться GREP-поиском для поиска примеров использования (http://www.community.terrasoft.ru/blogs/6250)
4. Получаем выбранное значение:

function wnd_VisesInObjectGridAreaOnNotify(ScriptableService, Sender, Message, Data) {
	if ((Sender.Tag == 'SelectVise') && (Message == MSG_OK)) {
// здесь обрабатывается ответ от него
// в функции AddVise берется ID типа визы: var ViseTypeID = Sender.Attributes('KeyValue');
		if (AddVise(Sender, Message)) {
			wnd_BaseGridAreaOnNotify(ScriptableService, Sender, Message, Data);
		}
	} else {
		wnd_BaseGridAreaOnNotify(ScriptableService, Sender, Message, Data);
	}
}
 
function btnAddOnClick(Control) {
// здесь открывается окно
	var Dataset = Services.GetNewItemByUSI('ds_Vises');
	var SelectViseWindow = ShowSelectDataWindowSimple(Dataset, 'Name',
		Self, true, 'SelectVise');
}

5. Запускаем создание записей Подарков:
5.1. Получить список контактов:

var Dataset = Services.GetNewItemByUSI('ds_Contacts');
var AccountIDs = GetGridSelectedIDsArray();
ApplyDatasetFilter(Dataset, 'AccountID', AccountIDs[0], true);
Dataset.Open();

5.2. для каждого контакта создать подарок:

while (!Dataset.IsEOF) {
	var ContactID = Dataset('ID');
	var ContactBirthDate = Dataset('BirthDate'); //или как поле дата рождения называется
	InsertGiftsForContact(ContactID, ContactBirthDate); // функция, которую вы напишете, использующая InsertQuery для добавления записей - примеры ищете в коде по InsertQuery 
	Dataset.GoToNext();
}
Показать все комментарии

Доброго времени суток, коллеги!

Есть инциденты, к которым могут быть привязаны файлы.
Есть контрагенты, к которым могут быть привязаны файлы.
Надо. На контрагенте видеть файлы, привязанные к его инцидентам. Лучше в общей куче с файлами, привязанными непосредственно к контрагенту, но это не критично.
Как сделать?

Нравится

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

Можно попробовать создать sq_FileInAccount добавив в нём UNION ALL tbl_FileInIncident через tbl_Incident.AccountID = tbl_FileInAccount.AccountID -> tbl_FileInIncident.IncidentID = tbl_Incident.ID

Кол-во колонок и их названия должны совпадать (используйте псевдонимы в unione).
При этом необходимо будет создать новый датасет ds_FileInAccount и перепривязать для раздела контрагенты в общем окне реестра "Файл в ..." компоненту dl_Data датасет ds_FileInItem на ds_FileInAccount

sq_FileInAccount создал по образу и подобию tbl_FileInAccount. По остальному вопрос. Какие поля втыкать в ds_FileInAccount? Хотел посмотреть по вроде аналогичному ds_FileInIncident, но там в sq_FileInIncident толпа полей, которые в sq_FileInAccount отсутствуют. И где делается перепривязка dl_Data?

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

В ds_FileInAccount, необходимо добавлять те поля которые Вы будете использовать, например ID, Link и т.д. Привязка dl_Data, происходит в не визуальных компонентах сервиса окна реестра.

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

Подскажите пожалуйста, как не выполнить определенный эвент, а не все, к примеру вот так
Dataset.DisableEvents('SelfOnDatasetAfterPost');
?
В случает такого значения аргументов выдает ошибку о некорректности аргументов.

Нравится

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

Метод DisableEvents() не принимает никаких аргументов, насколько я знаю. Поэтому тут нужно придумывать свою реализацию, к примеру:

Dataset.Attributes('DisableAfterPostEvent') = true;
Dataset.Post();
Dataset.Attributes('DisableAfterPostEvent') = false;

....

OnDatasetAfterPost(....,....) {
if(Dataset.Attributes('DisableAfterPostEvent')) {
return;
}

Вариант посложнее залезть в EventsDispatcher и отписаться от события.

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

Подскажите пожалуйста, как не выполнить определенный эвент, а не все, к примеру вот так
Dataset.DisableEvents('SelfOnDatasetAfterPost');
?
В случает такого значения аргументов выдает ошибку о некорректности аргументов.

Нравится

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