Недавно компания DocsVision запустила свой портал технической поддержки. В настоящий момент в нем есть специальная ветка для статей и вопросов по Конструктору Решений. Найти его можно по этой ссылке.
Несмотря на то, что часть статей взята из этого блога, там есть и статьи, которые не опубликованы здесь.
В дальнейшем часть из них будет перенесена в блог.
Свои вопросы можно по прежнему оставлять в блоге. Отвечать на них буду по возможности оперативно.
Мы обсуждаем следующие темы: Docsvision, редактирование и создание карточек документов, процесс, написание кода на C#
Темы обсуждений
бизнес-календарь
(2)
бизнес-процесс
(1)
блог
(3)
виды
(2)
дайджест
(1)
дополнительные сборки
(1)
изображение
(1)
карточки
(4)
кнопка
(1)
конструктор
(9)
литература
(1)
навигатор
(1)
настройка представлений
(1)
нумератор
(2)
ошибки
(3)
полезность
(1)
разметки
(2)
роли
(1)
сервер
(1)
сервис
(1)
скрипт
(12)
состояния
(1)
табличный контрол
(3)
уведомления
(1)
attribute
(1)
C#
(11)
DevExpress
(1)
DVCardManager
(2)
DVExplorer
(1)
HowTo
(18)
property
(3)
xml
(1)
XSLT
(1)
Поиск блогу
пятница, 9 сентября 2011 г.
понедельник, 8 августа 2011 г.
Рассылка уведомлений
В версии конструктора 4.5 есть сервис уведомлений.
С его помощью можно настроить рассылку уведомлений в виде ярлыка или почтового сообщения на изменения полей карточки. На данный момент уведомления рассылаются при изменении поля и последующем сохранении карточки. В связи с этим есть проблема, если необходимо отправить уведомление о смене состояния карточки. Для того, чтобы отправить такое уведомление, придется в скрипте карточки, меняющем ее состояние прописать принудительное изменение значения контрола состояния через PropertyController.UpdateProperty, либо (что будет оптимальнее при необходимости отправки нового состояния в уведомлении) записывать новое состояние в скрытый строковый контрол. Например, вот так:
С его помощью можно настроить рассылку уведомлений в виде ярлыка или почтового сообщения на изменения полей карточки. На данный момент уведомления рассылаются при изменении поля и последующем сохранении карточки. В связи с этим есть проблема, если необходимо отправить уведомление о смене состояния карточки. Для того, чтобы отправить такое уведомление, придется в скрипте карточки, меняющем ее состояние прописать принудительное изменение значения контрола состояния через PropertyController.UpdateProperty, либо (что будет оптимальнее при необходимости отправки нового состояния в уведомлении) записывать новое состояние в скрытый строковый контрол. Например, вот так:
CardData cStates = Session.CardManager.GetCardData(new Guid("{7984F2CE-9345-4C59-B66B-7125DD9195A1}"));// Получаем справочник ролевой модели. В нем хранятся состояния
PropertyController.UpdateProperty("СтрокаСостояния",cStates.Sections[new Guid("{521B4477-DD10-4F57-A453-09C70ADB7799}")].Rows[DomainObject.StateId].GetString("DefaultName"));// Получаем название текущего состояния и записываем его в контрол.
четверг, 21 июля 2011 г.
Изменение вида карточки
Предположим, что на карточке лежит контрол "Вид".
Опытным путем я установил, что при изменении значения в нем, само изменение вида карточки происходит уже после события ControlValueChanged.
Это означает то, что при написании ControlValueChanged для этого контрола нужно использовать PropertyController.GetPropertyValue("НазваниеКонтролаВида") вместо DomainObject.KindId, чтобы получить в скрипте новое значение вида.
Опытным путем я установил, что при изменении значения в нем, само изменение вида карточки происходит уже после события ControlValueChanged.
Это означает то, что при написании ControlValueChanged для этого контрола нужно использовать PropertyController.GetPropertyValue("НазваниеКонтролаВида") вместо DomainObject.KindId, чтобы получить в скрипте новое значение вида.
вторник, 12 июля 2011 г.
Скрипт на привязку карточки с табличному контролу.
Всем привет :-)
В одну из составляющих моей разработки решения"Управление совещаниями", входит объединение всех трёх карточек в единую работающую систему. Для этого мне требуется написать несколько скриптов на событие AddButtonClick табличного контрола. Мои познания в ООП находятся на уровне основных понятий, поэтому самостоятельно выполнить поставленную задачу будет крайне трудно, и если уважаемые разработчики помогут мне с преодолением этой проблемы, я буду им очень благодарен за проявленное содействие в достижении личных и организационных успехов.
Итак, задача:
В основной карточке "Совещание" ( Card 1 ) в таблице с вопросами повестки, при нажатии на добавить "+", должна появляться новая карточка "Вопросы повестки" ( Card 2 ). Так же, при каждом нажатии на добавить "+" карточка должна обновляться.

{
object newCard = Session.CardManager.CreateCard(new Guid("{5763AAF2-BF9B-4373-AF1B-6360EF4A2FFA}"));
}
но при загрузке карточки он выдаёт ошибку, что "Данный метод не поддерживается".
Вопрос : Какой скрипт будет выполнять поставленную задачу?
Спасибо)
Темы, поднимаемые в сообщении:
карточки,
конструктор,
табличный контрол
четверг, 30 июня 2011 г.
Как подключать сборки в конструкторе DocsVision
Рано или поздно придется столкнуться с подключением сборок в конструкторе.
Находятся все сборки по пути Windows/assembly/GAC_MSIL
Каталог скрытый, поэтому для доступа к нему через эксплорер необходимо включить отображение скрытых файлов и папок в свойствах папки.
Каждая сборка лежит в отдельной папке, поэтому подключать их придется по одной.
Из-за особенностей Конструтора у вас не получится подключить сборки сразу из assembly, поэтому скопируйте сначала нужные сборки в отдельную папку и уже оттуда подключайте. Но лучше удалить из GAC_MSIL скрытый файл "Desktop.ini". После этого папки со сборками станут видны из конструктора и их не придется никуда копировать. Также одном из плюсов данного способа является тот факт, что при переносе решения на другую машину, вам не придется заново прописывать пути к сборкам.
Для подключения сборки кликните на "+" в нижней таблице "Используемые дополнительные сборки" в окне редактирования скриптов конструктора, выберите нужную сборку и добавьте ее в таблицу.
Находятся все сборки по пути Windows/assembly/GAC_MSIL
Каталог скрытый, поэтому для доступа к нему через эксплорер необходимо включить отображение скрытых файлов и папок в свойствах папки.
Каждая сборка лежит в отдельной папке, поэтому подключать их придется по одной.
Из-за особенностей Конструтора у вас не получится подключить сборки сразу из assembly, поэтому скопируйте сначала нужные сборки в отдельную папку и уже оттуда подключайте. Но лучше удалить из GAC_MSIL скрытый файл "Desktop.ini". После этого папки со сборками станут видны из конструктора и их не придется никуда копировать. Также одном из плюсов данного способа является тот факт, что при переносе решения на другую машину, вам не придется заново прописывать пути к сборкам.
Для подключения сборки кликните на "+" в нижней таблице "Используемые дополнительные сборки" в окне редактирования скриптов конструктора, выберите нужную сборку и добавьте ее в таблицу.
Темы, поднимаемые в сообщении:
дополнительные сборки,
конструктор,
HowTo
Получение данных выделенной строки из таблицы
Вывод выделенной строки оказался весьма нетривиальным заданием.
Данный фрагмент кода выведет в MessageBox содержимое выделенной строки в табличном контроле с названием "Журнал заявки".
Для работы скрипта нужно прописать в using:
Возможно, что-то еще...
а также подключить сборки DevExpress. А именно
DevExpress.XtraLayout.9.2.dll
DevExpress.XtraGrid.9.2.dll
DevExpress.Data.9.2.dll
DevExpress.Utils.9.2.dll
Данный фрагмент кода выведет в MessageBox содержимое выделенной строки в табличном контроле с названием "Журнал заявки".
LayoutHelper layoutHelper = new LayoutHelper(CardControl.LayoutControl, CardControl.BarManager, Session, CardData.Type.Id);
DocsVision.BackOffice.View.WinForms.LayoutItems.ICustomPropertyItem propertyItem = layoutHelper.GetCustomPropertyItem("Журнал заявки");
var refMapper = new CardPropertyDescriptionMapper(Session);
DocsVision.BackOffice.Model.CardProperties.Entities.CardPropertyTable cpt = null;
foreach (DocsVision.BackOffice.Model.Layouts.Entities.CardPropertyTableDescription refPropertyTableDesc in refMapper.FindTableProperties(CardData.Type.Id))
{
if (refPropertyTableDesc.Name == "Журнал заявки")
{
var propertyMapper = new CardPropertyMapper(Session, CardData.Id, DomainObject.CustomPropertiesSectionId);
cpt = propertyMapper.FindTable(refPropertyTableDesc);
break;
}
}
System.Reflection.Assembly asm = System.Reflection.Assembly.Load("DocsVision.BackOffice.View, Version=4.5.0.0, Culture=neutral, PublicKeyToken=7148afe997f90519");
Type tableType = asm.GetType("DocsVision.BackOffice.View.WinForms.PropertyControls.TablePropertyControl");
var propInfo = tableType.GetProperty("GridView");
object ooo = propInfo.GetValue(propertyItem.Control, System.Reflection.BindingFlags.NonPublic, null, null, System.Globalization.CultureInfo.InvariantCulture);
DocsVision.BackOffice.View.WinForms.Controls.GridExView gridExView = ooo as DocsVision.BackOffice.View.WinForms.Controls.GridExView;
DevExpress.XtraGrid.Views.Grid.GridView gridView = gridExView as DevExpress.XtraGrid.Views.Grid.GridView;
object key = ((System.Data.DataRowView)gridView.GetFocusedRow()).Row[gridExView.KeyField];
foreach (DocsVision.BackOffice.Model.CardProperties.Entities.CardPropertyTableRow row in cpt.Rows)
{
if (row.Key == (Guid)key)
{
string message = "";
foreach (DocsVision.BackOffice.Model.CardProperties.Entities.CardProperty cellProp in row.Cells)
{
object val = cellProp.Value;
message += val == null ? "null" : val.ToString();
message += " ";
}
MessageBox.Show(message);
}
}
Для работы скрипта нужно прописать в using:
using DocsVision.Platform.WinForms.DataSource; using DocsVision.BackOffice.Model.CardProperties.DataAccess;
Возможно, что-то еще...
а также подключить сборки DevExpress. А именно
DevExpress.XtraLayout.9.2.dll
DevExpress.XtraGrid.9.2.dll
DevExpress.Data.9.2.dll
DevExpress.Utils.9.2.dll
Темы, поднимаемые в сообщении:
конструктор,
скрипт,
табличный контрол,
C#,
DevExpress,
HowTo
Добавление новой строки в табличный контрол из скрипта
Оговорю сразу, что данный метод работает, если для табличного контрола создана отдельная секция в карточке, так как добавление происходит через добавление записи в секцию.
Рассмотрим на примере таблицы, содержащей 3 столбца: Дату, идентификатор сотрудника и некоторый текст.
в приведенном скрипте:
secComment - это идентификатор табличной секции(Guid);
comment - какая-то строка(string)
Скрипт записывает текущую дату, пользователя, который открыл карточку в данный момент и некоторый текст.
Рассмотрим на примере таблицы, содержащей 3 столбца: Дату, идентификатор сотрудника и некоторый текст.
в приведенном скрипте:
secComment - это идентификатор табличной секции(Guid);
comment - какая-то строка(string)
Скрипт записывает текущую дату, пользователя, который открыл карточку в данный момент и некоторый текст.
Guid g = Guid.NewGuid();
CardData.Sections[secComment].BeginUpdate();
RowData newComment = CardData.Sections[secComment].CreateRow(g);
newComment.SetString("Текст", comment);
newComment.SetGuid("Автор", new EmployeeMapper(Session).GetCurrentUserId());
newComment.SetDateTime("Дата", DateTime.Now);
CardData.Sections[secComment].EndUpdate();
Темы, поднимаемые в сообщении:
конструктор,
скрипт,
табличный контрол,
HowTo
суббота, 21 мая 2011 г.
Смена атрибутов контрола из скрипта. На примере атрибута ReadOnly
Данный скрипт полезен в тех случаях, когда, например, измененное значение одного контрола влияет на доступность другого.
using System;
using System.Windows.Forms;
using DocsVision.Platform.ObjectManager;
using DocsVision.BackOffice.View.WinForms;
using DocsVision.BackOffice.Model;
using DocsVision.BackOffice.Model.Layouts.DataAccess;
using DocsVision.BackOffice.Model.Base.Entities;
using DocsVision.BackOffice.Model.CardProperties.Entities;
using DocsVision.BackOffice.Model.Layouts.Entities;
using DocsVision.BackOffice.Model.RoleModel.DataAccess;
using DocsVision.BackOffice.Model.RoleModel.Entities;
using DocsVision.BackOffice.View.WinForms.Helpers;
private void cardControl_AfterActivate(System.Object sender, System.EventArgs e)
{
CardProperty prop = GetCardProperty("имя контрола");
CardPropertyDescription.LayoutAttributeSet attrSet = prop.Description.GetLayoutAttributes(CardControl.DomainObject.SelectedLayoutId);
attrSet.ReadOnly = true;
PropertyController.Refresh();
}
//Поиск контрола с нужным именем
private CardProperty GetCardProperty(string propertyName)
{
foreach (CardProperty property in PropertyController.CardProperties)
{
if (property.Name == propertyName)
return property;
}
return null;
}
среда, 11 мая 2011 г.
Перезапуск сервисов из командной строки
Думаю, что многие сталкивались с проблемой, что какие-то изменения, внесенные в структуру DV требовали перезапуска серверов, SQL и IIS. На это уходит много времени, так как надо полазать по различным административным менюшкам и покликать много кнопок.
Я предлагаю вариант, когда перезапуск всех служб можно будет делать по двойному клику на ярлык на рабочем столе.
1. создаем новый текстовый файл.
2. в тело пишем
NET stop DVStorageServer45
NET stop WFServer45
NET stop MSSQL$SQLEXPRESS
IISReset
NET start MSSQL$SQLEXPRESS
NET start DVStorageServer45
NET start WFServer45
3. сохраняем файл на рабочий стол под именем Reset.bat и в свойствах файла выставляем "Запускать от имени Администратора". Иногда для этого приходится создать ярлык на этот батник и в его свойствах поставить запуск от имени администратора.
4. наслаждаемся перезапуском в один клик.
P.S. Возможно, что SQL сервер у вас называется не SQLEXPRESS. В таком случае либо просто удалите из батника строку перезапуска SQL (Обычно такой перезапуск не требуется), либо впишите свое название сервера.
Я предлагаю вариант, когда перезапуск всех служб можно будет делать по двойному клику на ярлык на рабочем столе.
1. создаем новый текстовый файл.
2. в тело пишем
NET stop DVStorageServer45
NET stop WFServer45
NET stop MSSQL$SQLEXPRESS
IISReset
NET start MSSQL$SQLEXPRESS
NET start DVStorageServer45
NET start WFServer45
3. сохраняем файл на рабочий стол под именем Reset.bat и в свойствах файла выставляем "Запускать от имени Администратора". Иногда для этого приходится создать ярлык на этот батник и в его свойствах поставить запуск от имени администратора.
4. наслаждаемся перезапуском в один клик.
P.S. Возможно, что SQL сервер у вас называется не SQLEXPRESS. В таком случае либо просто удалите из батника строку перезапуска SQL (Обычно такой перезапуск не требуется), либо впишите свое название сервера.
Скрипт смены состояния карточки из бизнес-процесса
К сожалению, стандартными процедурами бизнес-процесса невозможно изменить состояние карточки. Для изменения состояния нужно поставить элемент "Скрипт" и написать в нем код, представленный ниже.
Важно помнить о следующей структурной особенности состояний: они различны у каждого вида карточки, поэтому сначала надо получать текущий вид карточки, а затем выбирать соответствующее ему состояние.
Важно помнить о следующей структурной особенности состояний: они различны у каждого вида карточки, поэтому сначала надо получать текущий вид карточки, а затем выбирать соответствующее ему состояние.
// подключение системных библиотек
using System;
using System.Xml;
// подключение библиотек СУБП
using DocsVision.Workflow.Objects;
using DocsVision.Workflow.Runtime;
using DocsVision.Workflow.Gates;
using DocsVision.Platform.HelperAPI;
using DocsVision.Platform.ObjectManager;
namespace DVScriptHost
{
class DVScript
{
// стандартная функция, которая будет вызвана подсистемой СУБП
//
// входные параметры функции:
//
// process - информация о процессе. содержит коллекции
// Gates - коллекция шлюзов процесса
// Variables - коллекция переменных процесса
// passInfo - информация о текущем проходе
//
private string state = "Согласование с контрагентом"; //Название состояния, в которое мы хотим перевести карточку
private DVGate m_DVGate;
public void Execute (DocsVision.Workflow.Runtime.ProcessInfo process, PassState passInfo)
{
try
{
//Получаем ссылку на карточку, у которой надо сменить состояние. В данном случае она хранится в переменной процесса, которая называется "Инициирующий договор"
ProcessVariable pvCard = process.GetVariableByName("Инициирующий договор");
DVCard dvCard = (DVCard)pvCard.Value;
//получаем шлюз
m_DVGate = (DVGate)process.Gates[DVGate.GateID];
// получаем сессию
UserSession oSes = m_DVGate.Session;
//Получаем данные карточки
CardData card = oSes.CardManager.get_CardData(dvCard.ID);
//Получаем ссылку на секцию "Основная информация". Так как карточка стандартная, то гуид берем из справочника в предыдущем посте. В противном случае - из DVExplorer.
SectionData mainInfo = card.Sections["8C77892A-21CC-4972-AD71-A9919BCA8187"];
//Получаем ссылку на справочник типов. Гуид берем из справочника в предыдущем посте.
CardData RefTypes = oSes.CardManager.get_DictionaryData("BE14D55D-92B7-4345-AD10-32588981F83D");
//Получаем тип карточки из справочника типов
RowData currentType = RefTypes.Sections["49AD5A2D-17EC-46E2-A49E-C58D0BBD9C1A"].Rows[mainInfo.FirstRow.get_Value("Type")];
//Устанавливаем состояние карточки, найдя его по имени и в соответствии с типом карточки
mainInfo.FirstRow.set_Value("DocState", currentType.ChildRows.GetItemByValue("Name", state).ID);
}
catch (Exception ex)
{
// запись в журнал ошибки исполнения
process.LogMessage("Ошибка выполнения скрипта:" + ex.Message);
}
return;
}
}
}
Темы, поднимаемые в сообщении:
бизнес-процесс,
скрипт,
состояния,
C#,
HowTo
Подписаться на:
Сообщения (Atom)