Здравствуйте. Я вместе с группой опытных программистов разрабатываю редактор скриптов Terrasoft CRM, который на данный момент включает в себя такие возможности как автодополнение, полная подсветка синтаксиса и еще несколько функций необходимых полноценному редактору. Предположительная стоимость продукта - $ 199 за одну лицензию. Интересно знать Ваше мнение по разрабатываемому продукту. Что бы Вы хотели видеть в данном редакторе, готовы ли Вы или Ваша компания купить данный продукт для удобства разработки и, как следствие, роста Вашей продуктивности работы?

Нравится

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

Скрины в студию!

Хотелось бы увидеть демонстрацию функциональных возможностей в видео формате.

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

Андрей, сейчас редактор скрипта (как и дизайнеры других сервисов) улучшается и в версии 3.4.1 добавлено немало полезной функциональности. Например, функция автодополненния кода (CodeCompletion) пересматривается и возможно будет расширена дополнением по классам ядра.

Уточните, чего именно вам не хватает в редакторе скрипта в TSAdmin? Возможно это уже будет в новой версии 3.4.1.

Планируется редактор только скриптов, без других типов объектов?
А не рассматривали вариантов в виде плагина к навороченной IDE вроде MSVS?

Уточните, чего именно вам не хватает в редакторе скрипта в TSAdmin? Возможно это уже будет в новой версии 3.4.1.

Хотелось бы подсветку выделенного слова и его совпадение в функции.

Константин, так сейчас выглядит мой дизайнер скрипта в TSAdmin (версия 3.4.1.62):

Все похожие слова при выделении или при поиске слова выделяются.

Вот настройки дизайнера скриптов в TSAdmin (можно выбрать цвет фона, размер и цвет шрифта, цвет выделения похожих слов и т.д.):
Окно опций

Интересно, продукт вышел?

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

Часто возникает потребность раздавать права доступа после назначения ответственного. Дело в том, что принцип раздачи прав на записи действует не всюду. В случае задач все будет происходить именно таким образом.
Но, к примеру, для контрагентов это не действует. Чтобы это действовало для необходимых разделов, следует в Terrasoft Administrator’e открыть скрипт обработки датасета, в нем найти функцию SelfOnDatasetAfterPost и дописать следующую строку:

GiveRightsToRecordOwner(Dataset);

Затем сохраните изменения.

/system/files/04.05.png

Нравится

Поделиться

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

О, Боже, а мы строили такие безумные схемы... :)
Спасибо!

А при импорте из Excel этого происходить не будет?

Нет, при импорте права раздаются по настройкам прав доступа по умолчанию.

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

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

1. Открыть скрипт scr_WorkflowWorkspace
2. Найти функцию ApplyWorkflowsWorkspaceFilter
3. Закомментировать строку

ApplyDatasetFilter(BaseWorkspace.GridDataset, 'OwnerID',
                Connector.CurrentUser.ContactID, !Connector.CurrentUser.IsAdmin);

1

Нравится

Поделиться

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

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

Скрипт принимает один единственный параметр - полное имя файла бекапа.
Перед использованием необходимо отредактировать скрипт и настроить параметры под себя:

  • DestinationPath - путь, где будет развернут заданный бекап
  • ServerName, UserName, Password - параметры соединения с СУБД

После выполнения скрипта, в папке DestinationPath будет создана папка с именем базы, в которой будут храниться файлы данных и лога и произойдет связывание пользователя Supervisor с одноименным логином.

Нравится

Поделиться

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

Сергей, я так понимаю Restore.sql отсутствует потому как в cmd написано

 del Restore.sql

:)

Именно - это временный файл. После его выполнения в нем уже нет надобности.

Теперь понял. А почему сразу не выполнить этот запрос через osql?

Сначала так и пробовал. Текст запроса оказался слишком большим для такого способа выполнения.

Здорово :) Я мечтала о такой штуке, а теперь она есть! :)

Уххх. Давно было пора.

Сереж, а можно сразу для восстановленной базы проводить сопоставление fkeys? Куда это добавить в скрипт?

Можно продублировать предпоследнюю строку и в ней заменить

exec sp_change_users_login 'Auto_Fix', 'Supervisor'

на

exec sp_change_users_login 'update_one', 'fkeys', 'fkeys'

Я бы добавил еще несколько улучшений:
1. Передача параметров через командную строку. Постоянно править файл неудобно. И если не передали, то спросить пользователя в консоли.
2. Добавить поддержку Windows авторизации
3. Обработать корректно если система не знает где утилита osql - в переменной PATH не добавлен путь или вы запустили файл не в папке с osql.

Для меня эти все опции, которые правятся в скрипте, статичны. И было бы не удобно их все время вводить в параметрах скрипта. Как варинат можно анализировать, если соотв-ий параметр не задан, то использвать константное значение.

Сергей, все верное - часть параметров очень часто статична: имя пользователя, пароль, сервер, а вот Имя БД, имя файла бекапа в моем случае нет, то править все время файл не удобно или хранить много таких скриптов или сделать самые часто изменяемые параметры - опциональными.

Добавил такую возможность.
Теперь, если задан второй параметр, то он воспринимается как имя базы, иначе имя базы определяется по имени файла бекапа.
Если задан третий параметр, то он воспринимается как папка, в которую будут помещены файлы БД, иначе - этот параметр берется из переменной DestinationPath, указанной в скрипте.

Эти два параметра не обязательные. Архив со скриптом обновил.

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

Данный функционал можно реализовать, например, следующим образом:

1. В TS Admin в sq_FileInItem необходимо добавить колонку с текстом SQL следующим образом:

cast (round (cast (datalength([FileData]) AS float) / cast (1048576 AS float) , 2) AS varchar(10)) + ' MB'

scr1

2. Добавить строковое поле в ds_FileInItem:

scr2

3. Добавить колонку в окно wnd_FilesDetailGridArea:

scr3

4. Перезапустите TS Client и проверьте функционал:

scr4

Нравится

Поделиться

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

Отличная идея!

Инна, я бы предложил завести в таблице tbl_File колонку Размер и при добавлении файла вместе с файлом записывать его размер.

Преимущества:
1. Не нужно усложнять запрос, не нужно на каждую строку данных выполнять расчет размеров BLOB-поля, а сразу добавлять в конфигурации значение размера непосредственно в колонку, при обновлении содержимого файла - обновлять и размер
2. Это будет работать как для файлов, прикрепленных полностью, так и для файлов прикрепленных по ссылке (если это ссылка на файл)
3. Не нужно будет писать custom-sql поле, а значит по этой колонке можно будет нормально сортировать, фильтровать и т.д, и что самое главное - это можно реализовать в базовой версии, т.к. конфигурация базовой версии одна и не зависит от конкретной СУБД - решение будет универсальным

Спасибо, Саша!

Да, преимуществ много...
Мы уже зарегистрировали пожелание для реализации в коробке.
Пользователи будут вам благодарны :smile:

Это было бы шикарно и во внутренней и в базе. а еще иконку в зависимости от типа файлов

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

Часто в работе на проектах необходимо использовать вызов хранимых процедур SQL из скриптов Terrasoft. В случаи вызова процедур в одном/двух случаях можно описать вызов вручную, когда же таких вызовом множество их описание становится нудным даже при условии копипаста.

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

Описание функций:
ExecuteSQL(SQLText, Names, Types, Values) - выполняет SQL скрипт с указанными параметрами
• SQLText - текст SQL скрипта
• Names - массив имен параметров
• Types - массив типов параметров, в соответствии с порядком следования элементов параметра Names
• Values - массив значений параметров, в соответствии с порядком следования элементов параметра Names

ExecuteSQLWithoutParameters(SQLText) - выполняет SQL скрипт без указания параметров
• SQLText - текст SQL скрипта

ExecuteSQLWithReturnParameter(SQLText, Names, Types, Values, ReturnName) - выполняет SQL скрипт с указынными параметрами и возвращает результат
• SQLText - текст SQL скрипта
• Names - массив имен параметров
• Types - массив типов параметров, в соответствии с порядком следования элементов параметра Names
• Values - массив значений параметров, в соответствии с порядком следования элементов параметра Names
• ReturnName - название возвращаемого параметра

Коды функций:

function ExecuteSQL(SQLText, Names, Types, Values) {
        var Parameters = CreateSPParameters();
        var i = 0;
        while (i Names.length) {
                CreateSPParameter(Parameters, Names[i], Types[i], Values[i]);
                i++;
        }
        Connector.DBEngine.ExecuteCustomSQL(SQLText, Parameters);
}

function ExecuteSQLWithoutParameters(SQLText) {
        Connector.DBEngine.ExecuteCustomSQL(SQLText, System.EmptyValue);
}

function ExecuteSQLWithReturnParameter(SQLText, Names, Types, Values, ReturnName) {
        var Parameters = CreateSPParameters();
        var i = 0;
        while (i Names.length) {
                CreateSPParameter(Parameters, Names[i], Types[i], Values[i]);
                i++;
        }
        Parameters.ItemsByName(ReturnName).ParamType = 1;
        Connector.DBEngine.ExecuteCustomSQL(SQLText, Parameters);
       
        var Result = Parameters.ItemsByName(ReturnName).ValAsInt;
        return Result;
}

Примеры использования:

var SQLText = 'CheckCardSelectingOffering :OfferingInWarehouseID, ' +
             ':CardSelectionID, :ReturningCustomer, :CancelSelection, :Result OUTPUT';
var Names = new Array('OfferingInWarehouseID', 'CardSelectionID',
             'ReturningCustomer','CancelSelection', 'Result');
var Types = new Array(pdtGUID, pdtGUID, pdtGUID, pdtGUID, pdtInteger);
var Values = new Array(OfferingDataset('ID'), CardSelectionID, wartypReturningCustomer,
             wartypCancelSelection, 0);
var Result = ExecuteSQLWithReturnParameter(SQLText, Names, Types, Values, 'Result');

var SQLText = 'CalcAccountAmounts :AccountID, :Held, :CardSelection, ' +
           ':Platezh, :Paid';
var Names = new Array('AccountID', 'Held', 'CardSelection', 'Platezh', 'Paid');
var Types = new Array(pdtGUID, pdtGUID, pdtGUID, pdtGUID, pdtGUID);
var Values = new Array(AccountID, warstateHeld, wartypCardSelection, doctypePlatezh,
           docstatPaid);
ExecuteSQL(SQLText, Names, Types, Values);

Нравится

Поделиться

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

У меня возник вопрос по поводу скрипта, в частности scr_Dataflow1CUtils.
В этом скрипте вначале обьявляется глобальная внутри скрипта переменная:

var Connections = {};

В этой переменной впоследствии будут храниться все активные подключения к 1С.
Если этот скрипт был инициализирован во время запуска синхронизации из раздела "Интеграции", что будет если я обращусь к скрипту через вот такой код в скрипте scr_Main:
var ScriptItem = Services.GetSingleItemByID(ServiceScriptID);
, где ServiceScriptID - это ID скрипта сервиса 'scr_Dataflow1CUtils'.
Смогу ли я через обращение ScriptItem.Connections получить список подключений или эта переменная будет пустой, хотя подключения были уже проиниициализированы и выполнены.
То есть будет ли это одна и та же сущность скрипта, что используется в момент подключения к 1С и в момент обращения из скрипта scr_Main?

Во время закрытия CRM у меня вызывается функция закрытия всех 1С подключений. Изначально я подключил скрипт scr_Dataflow1CUtils в скрипт scr_Main и пользовался следующей функцией для закрытия подключений:

function Disconnect1CConnections(){
        for (var j in scr_Dataflow1CUtils.Connections) {
                if (scr_Dataflow1CUtils.IsConnected(j)) {
                        scr_Dataflow1CUtils.Disconnect(j, true);
                }
        }
}

Сейчас я хотел бы исключить подключаемый скрипт scr_Dataflow1CUtils, чтобы уменьшить время на инициализацию CRM при ее запуске, но каким-то образом все таки выполнять закрытие всех соединений при выходе из CRM.

Нравится

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

Переписал функцию отключения соединений с 1С следующим образом и она работает:

function Disconnect1CConnections(){
	var ScriptItem = Services.GetSingleItemByUSI('scr_Dataflow1CUtils');
	for (var j in ScriptItem.ScriptControl.CodeObject.Connections) {
		if (ScriptItem.ScriptControl.Run('IsConnected', j)) {
			ScriptItem.ScriptControl.Run('Disconnect', j, true);
		}
	}
}

Таким образом я отключил скрипт scr_Dataflow1CUtils из скрипта scr_Main, что позволило пропустить инициализацию этого скрипта во время загрузки CRM, и перенести время инициализации на момент закрытия CRM (конечно, если перед этим скрипт не был уже инициализирован. В таком случае он просто берется из кэша).

"Кошкаров Андрей" написал:То есть будет ли это одна и та же сущность скрипта, что используется в момент подключения к 1С и в момент обращения из скрипта scr_Main?

Да. ScriptItem.ScriptControl.CodeObject.Connections действительно будет ссылаться на один и тот же екземпляр объекта. Даже в случае следующего кода

	var EditWindow1 = Services.GetNewItemByUSI('wnd_1CSynchro');
	var EditWindow2 = Services.GetSingleItemByUSI('wnd_1CSynchro');
        var ScriptItem = Services.GetSingleItemByUSI('scr_Dataflow1CUtils');
        var test = EditWindow1.ScriptControl.CodeObject.Connections == EditWindow2.ScriptControl.CodeObject.Connections
        var test2 = ScriptItem.ScriptControl.CodeObject.Connections == EditWindow2.ScriptControl.CodeObject.Connections

переменные test, test2 - будут содержать true.
Но по хорошему, лучше хранить объект Connections в атрибутах коннектора:
Connector.Attributes('1CConnecctions') = {}
Нужно как минимум переписать scr_Dataflow1CUtils для этого.
В будущих версиях будет учтена необходимость отключения 1С соединений.

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

Друзья, кто из вас организовывал хранение файлов при помощи FileStream?
Если да, то не могли бы вы поделиться опытом?
Рассказать в чем плюсы и минусы?
И как можно перейти от хранения файлов в таблице tbl_Files к хранению файлов в файловой системе при помощи file stream?

Нравится

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

Вот есть хорошая статья по организации FileStream
http://blogs.msdn.com/b/alexejs/archive/2009/06/03/filestream.aspx
Основное достоинство этой технологии - это то что объем хранимой информации не влияет на общий объем БД, а следовательно можно пользоваться MS SQL Server 2008 R2 Express Edition бесплатно еще какое-то время, пока база не станет объемом 4 Gb.

Туда бы еще и содержимое tbl_MailMessage отправить:smile:

Основной размер писем составляют аттачи. В новой версии почтового клиента аттачи вынесены в tbl_Files. Именно с этой целью. :wink:

"Евгений Либин" написал:В новой версии почтового клиента

кстати сразу еще один дополнительный + к выбору именно вашей версии выходит при условии реализации внешнего хранения файлов - убираем из бюджета Outlook и полновесный SQL server:smile:

Кстати, в инете не раз находил информацию о том что в MS SQL 2008R2 Expr. ed. размер базы увеличен с 4Гб до 10Гб, но на сайте микрософта подтверждения не нашел. Если это правда - то тогда это супер.

Строго говоря и 4Гб без хранения файлов и подобного более чем достаточно было бы... правда, там еще ограничения конечно есть в плане процессоров, памяти и т.д, да и про tbl_SystemLog со скриншотами не забываем:) в рамках оффтопика...

"Евгений Либин" написал:Вот есть хорошая статья по организации FileStream
http://blogs.msdn.com/b/alexejs/archive/2009/06/03/filestream.aspx
Основное достоинство этой технологии - это то что объем хранимой информации не влияет на общий объем БД, а следовательно можно пользоваться MS SQL Server 2008 R2 Express Edition бесплатно еще какое-то время, пока база не станет объемом 4 Gb.

спасибо, Евгений :) очень познавательно.

кстати, а как быть с backup? как происходит бэкап данных при использовании filestream?

Hello, colleagues !
This link really helped, thank You :). Have You tested the solution with table tbl_Files? I noticed, that some "instead of" triggers have to be removed to be able to change column FileDate datatype from Image to Varbinary, that use FileStreams. This cause access rights functionality.

Это решение уже кто-то в реальном проекте использовал? Или всё на стадии интереса?

"Евгений Либин" написал:Основной размер писем составляют аттачи. В новой версии почтового клиента аттачи вынесены в tbl_Files. Именно с этой целью.

У нас например за два года работы эта таблица выросла уже до 36гб (лимит Firebird), есть ли наработки по разделению таблицы tbl_Files на несколько? Например с UNION в SELECT запросе и подмене в INSERT`е и насколько это повлияет на производительность?

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

К сожалению у нас не было опыта в разделении таблицы tbl_Files. Производительность, естественно, незначительно уменьшиться. Для того чтобы получить конкретные данные - необходимо тестирование.

Спасибо Дмитрий, значит будем тестировать...

Добрый день!
Возвращаясь к filestream, можно его все-таки использовать в Террасофте для таблицы файлов или нет?
TS 3.4.1.
SQL 2014
Террасофт умеет работать с данными типа varbinary(max) filestream?

1) включили возможность файстрима на сервере
2)создали файловую группу для базы
3)в качестве проверки функциональности создали новую таблицу через sql, там поле varbinary(max) filestream-засунули туда данные через sql - ну тут все ок
4) добавили в таблицу tbl_Files новое поле FileData1 varbinary(max) filestream; (перед этим пришлось удалить триггер к этой таблице - на instead of delete)
5) Пошли в террасофт администратор, там взяли в таблице tbl_Files, полe FileData сменила на FileData1 (не меняя при этом тип, и не сохраняя в бд потом таблицу (потому как не видим типа varbinary в приложении), пошли в sq_Files - там выбрали FileData1 вместо FileData.
6) Зашла в террасофт, добавили файл, файл даже добавился файловую группу, но террасофт его не может потом прочесть, потому что видимо не подозревает про тип варбинари с признаком файлстрим

Работа с filestream обсуждалась тут и тут. Также тут обсуждают альтернативные реализации с хранением в другой базе.

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

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

Не отрабатывают скрипты во вкладке Соглашения, никаких ошибок при этом не возникает,
версия программы - 2.8.12.39

Не подскажете как это исправить?

Нравится

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

Не помню такой вкладки... неужели я настолько забыл 2.8:sad: подскажите, где найти ее?

Извиняюсь за преждевременный вопрос, нашёл причину - лишний end )))

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

Добрый день!
Есть бизнес-процесс, который стартует например, в разделе "Договоры".
При выполнении определенных шагов(задач) выполняются скрипты в бизнес-процессе, которые вызывая хранимую процедуру, изменяют некоторые поля в договоре (статус и т.п.).
Но чтобы увидеть эти изменения, необходимо нажать на кнопку "Обновить" в гриде Договоров.
Подскажите, пожалуйста, как можно сделать так, чтобы запись обновилась автоматически?

Нравится

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

Можно, например, в скрипте после выполнения процедуры вставить такой код:

var ActiveWorkspace = Connector.Attributes('MainWindow').ComponentsByName('wndWorkspace').Window;
if (ActiveWorkspace.Name == 'wnd_ContractsWorkspace') {
	var GridDataset = ActiveWorkspace.ComponentsByName('dlContracts').Dataset;
	RefreshDataset(GridDataset);
}

Если на момент выполнения скрипта будет активным раздел "Договоры", его реестр обновится.

Спасибо

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