вторник, 28 апреля 2015 г.

Создание и открытие карточки DocsVision версии 4.5.1988 на редактирование из Lotus Script и других VB подобных языков

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

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

Иначе скрипт не будет знать какого вида создавать карточку. Можно дописать и сделать выбор конкретного вида из списка видов, назначенных на папку. Но в данном случае было сделано так. Запускающим методом является процедура newCard.
Для работоспособности данного кода также необходимо, чтобы на рабочей станции, где будет запускаться скрипт был установлен клиент DocsVision 4.5.1988.
Данный код тестировался в Lotus Script. Скорее всего он будет работать и в других VB подобных языках программирования. Может быть с небольшой корректировкой.

Код:
Sub newCard()
Const ID_DICFOLDERSCARD = "{DA86FABF-4DD7-4A86-B6FF-C58C24D12DE2}" ' ИД карточки папок
Const ID_CARDIN = "{C1FED883-08DE-420F-8FB4-C16CEFFC1630}" ' ИД карточки типа входящий
Const ID_CARDINT = "{425DD1AC-8DF1-49F0-9A06-FA61381C4FEC}" 'ИД карточки типа внутренний
Const ID_CARDOUT = "{FA0C389E-1095-4BC1-BEDC-793463742571}" 'ИД карточки типа исходящий
Const ID_CARDARCH = "{A9E3F102-355B-477D-A9F2-99B02579F34E}" ' ИД карточки типа архивный
Const ID_CARDUNI = "{E724C058-B678-42FE-9C73-441705698CDB}" ' ИД карточки универсальный

' Строка подключения к серверу DocsVision по протоколу named pipe
'можно сделать и протоколу http. Как будет лучше так и сделать
Const ConnectString = "\\srv-dv\Pipe\DocsVision45\StorageServer"

Dim oSession As Variant
Dim Manager
Dim oTypesObject

Dim host As Variant
Dim oCard
Dim Navigator
Dim RowMainInfo


Set Navigator = CreateObject("DVNavigator.NavigatorControl")
Set Manager = CreateObject("DVObjectManager.SessionManager")
Set oTypesObject = CreateObject("TOHelperObjects.TypesObject")

Manager.Connect ConnectString
Set oSession = Manager.CreateSession()
If oSession Is Nothing Then
Msgbox "Невозможно создать сессию к DocsVision! За помощью обратитесь к администратору."
Exit Sub
End If

Set oTypesObject.UserSession = oSession

Set host = Navigator.CreateHost(oSession)

' Получаем карточку папок
Set oFolderCard = oSession.CardManager.Dictionary(ID_DICFOLDERSCARD)

' Выводим форму для выбора папки
FolderID = host.SelectFolder("Выбор папки для создаваемой карточки.")

' Получаем ИД вида документа по папке
DocsViewID = GetDocViewID(oFolderCard, FolderID)
If DocsViewID = "" Then
Msgbox "Для данной папки не удалось получить вид создаваемых документов. За помощью обратитесь к администратору."
Exit Sub
End If

' Получаем тип документа (Входящий = 0, Исходящий = 1, Внутренний = 2, Архивный = 3, Универсальный = 4)
DocType = GetDocTypeByDocView(oSession, DocsViewID)

' В зависимости от типа документа копируем в переменную DocTypeID соответствующий ИД типа документа
If DocType = -1 Then
Msgbox "Ошибка получения типа документа. За помощью обратитесь к администратору."
Exit Sub
End If
If DocType = 0 Then
DocTypeID = ID_CARDIN
End If
If DocType = 1 Then
DocTypeID = ID_CARDOUT
End If
If DocType = 2 Then
DocTypeID = ID_CARDINT
End If
If DocType = 3 Then
DocTypeID = ID_CARDARCH
End If
If DocType = 4 Then
DocTypeID = ID_CARDUNI
End If

' Создаем карточку документа
Set CardData = oSession.CardManager.CreateCardData(DocTypeID)
' Получаем первую строку основной секции карточки
Set RowMainInfo = CardData.Sections(CardData.Type.Sections.GetByAlias("MainInfo").ID).FirstRow
RowMainInfo.Value("Name") = "Имя документа"
Call oTypesObject.SetCardType(CardData.ID, DocsViewID, True, True, False, True, True, True, True)

'Здесь прописываются значения свойств документа. 
' В закомментрированном ниже коде свойству Name присвоено значение: Test oMailItem.Subject 
'Можно добавить свои свойства
' Set oName = GetProperty("Name", CardData, DocType)
' oName.Value("Value") = "Test oMailItem.Subject"
' oName.Value("TextValue") = "Test oMailItem.Subject"
' oName.Value("DisplayValue") = "Test oMailItem.Subject"


' Создаем слабый ярлык на карточку в выбранной папке
oFolderCard.CreateShortcut FolderID, CardData.ID, True

' Обновляем данные карточки
CardData.Refresh

' Отображаем карточку
host.ShowCard CardData.ID
End Sub

Function GetDocViewID(oFolderCard, FolderID)
GetDocViewID = ""
Set AllowedForFolderTypes = Nothing

'Получаем объект карточка папок
'    Set oFolderCard = UserSession.CardManager.Dictionary(ID_FOLDERSCARD)

'Получаем объект папки в которой будет храниться карточка
Set oFolder = oFolderCard.GetFolder(FolderID)

'Получаем разрешенные для папки типы и возвращаем их из функции
'Если на папку не включено ограничение на создаваемые виды возвращаем Nothing, иначе список разрешенных видов
If (oFolder.Restrictions And FOLDER_RESTRICTED_TYPES) <> FOLDER_RESTRICTED_TYPES Then
Set AllowedForFolderTypes = Nothing
Else
Set AllowedForFolderTypes = oFolder.AllowedTypes
End If

If AllowedForFolderTypes Is Nothing Then
Msgbox "На папке не стоит ограничение на виды создаваемых в ней карточек. Карточка не будет создана. За помощью обратитесь к администратору."
Exit Function
End If

If AllowedForFolderTypes.Count = 0 Then
Msgbox "В списке ограничений папки на создаваемые виды не стоит ни один вид. Карточка не будет создана. За помощью обратитесть к администратору."
Exit Function
End If

If AllowedForFolderTypes.Count > 1 Then
Msgbox "В списке ограничений папки на создаваемые виды установлен больше чем один вид. Карточка не будет создана. За помощью обратитесь к администратору."
Exit Function
End If

GetDocViewID = AllowedForFolderTypes.Item(0).TypeID

End Function

Function GetDocTypeByDocView(UserSession, DocsViewID)
' По умолчанию тип карточки равен -1 (Теоретически. Что в принципе не может быть,
' так как у вида документа не может не быть типа карточки.)
'ID карточки типов
Dim oSectDocType As Variant
Const ID_TYPESCARD = "{BE14D55D-92B7-4345-AD10-32588981F83D}" 'ИД Карточки справочника типов
GetDocTypeByDocView = -1

Set oTypesCard = UserSession.CardManager.DictionaryData(ID_TYPESCARD)
Set oSectDocType = oTypesCard.Sections(oTypesCard.Type.AllSections.GetByAlias("DocumentTypes").ID)
Forall Row In oSectDocType.AllRows
If Row.Value("RowID") = DocsViewID Then
GetDocTypeByDocView = Row.Value("DocumentType")
Exit Function
End If
End Forall

End Function

Function GetProperty(tName, CardData, DocType)
Const ID_SECTPROP_CARDIN = "{B822D7D1-2280-4B51-AE58-A1CF757C5672}" 'Секция свойства карточки входящий документ
Const ID_SECTPROP_CARDINT = "{ 5B6B407E-3D72-49E7-97D9-8E1E028C7274}" 'Секция свойства карточки внутренний документ
Const ID_SECTPROP_CARDOUT = "{13A6A514-DC45-4078-AD02-66A79F896E68}" 'Секция свойства карточки исходящий документ
Const ID_SECTPROP_CARDARCH = "{ECD7A672-22E3-4748-9962-00FC0FE2ABBC}" 'Секция свойства карточки архивный документ
Const ID_SECTPROP_CARDUNI = "{D25F1089-C63D-43E1-9FA4-864C48EECCB4}" 'Секция свойства карточки универсальный документ

If DocType = 0 Then
Set oProp=CardData.Sections(ID_SECTPROP_CARDIN)
End If
If DocType = 1 Then
Set oProp=CardData.Sections(ID_SECTPROP_CARDOUT)
End If
If DocType = 2 Then
Set oProp=CardData.Sections(ID_SECTPROP_CARDINT)
End If
If DocType = 3 Then
Set oProp=CardData.Sections(ID_SECTPROP_CARDARCH)
End If
If DocType = 4 Then
Set oProp=CardData.Sections(ID_SECTPROP_CARDUNI)
End If

Set oProp=CardData.Sections(ID_SECTPROP_CARDIN)
Set oPropRow=oProp.FindRow("@Name='" & tName & "'")
Set GetProperty=oPropRow

End Function

четверг, 3 апреля 2014 г.

Вызов хранимых процедур без прямого подключения к SQL

ExtensionMethod extensionMethod = session.ExtensionManager.GetExtensionMethod("BackOfficeExtension", "ResetRolesCache");
if (extensionMethod == null)
 return;
extensionMethod.Parameters.AddNew("cardId", ParameterValueType.Guid, cardId);
extensionMethod.Execute();


Хранимую процедуру можно вызвать также из клиентского скрипта:

Set Report = UserSession.ReportManager.Reports("{4958AEC9-5E38-4D83-ABF2-E92120D04F80}")

 Report.Parameters("TaskID").Value = TaskID
 Report.Parameters("PerformerID").Value = sCurrentUserID

Report.GetData

пятница, 4 октября 2013 г.

DV 5.1.2344 Добавление ссылки на карточку в другую карточку

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

using System;
using DocsVision.BackOffice.CardLib.CardDefs;
using DocsVision.Platform.ObjectModel;
using DocsVision.BackOffice.ObjectModel;
using DocsVision.BackOffice.ObjectModel.Services;
using Docsvision.DocumentsManagement;
using DocsVision.Platform.ObjectModel.Search;


        /// <summary>
        /// В список ссылок документа добавляет связанный документ
        /// </summary>
        /// <param name="document">карточка документа в который добавляется ссылка на другую карточку</param>
        /// <param name="addeddocument">карточка добавляемого документа в качестве ссылки в карточку другого документа</param>
        /// <param name="LinkName">Имя связи из справочника ссылок</param>
        private void CreateRefInCard(Document document, Document addeddocument, string LinkName)
        {
            IReferenceListService referenceService = CardControl.ObjectContext.GetService<IReferenceListService>();
           

            ReferenceList referenceList;
            if (document.MainInfo.ReferenceList == null)
            {
                referenceList = referenceService.CreateReferenceList();
                CardControl.ObjectContext.SaveObject(referenceList);
           
                document.MainInfo.ReferenceList = referenceList;
            }
            else
            {
                referenceList = document.MainInfo.ReferenceList;
            }
       
            LinksLinkType linkType = CardControl.ObjectContext.FindObject<LinksLinkType>(new QueryObject("LinkName", LinkName));
           
            Guid CardTypeID = CardControl.Session.CardManager.GetCardData(CardControl.ObjectContext.GetObjectRef(addeddocument).Id).Type.Id;
           
            referenceService.CreateReference(referenceList, linkType, CardControl.ObjectContext.GetObjectRef(addeddocument).Id, CardTypeID, false);
            CardControl.ObjectContext.AcceptChanges();
        }

воскресенье, 5 мая 2013 г.

Добавление нового свойства в карточку доп командой навигатора

for each SelectCard in SelectionIDs
   Set CardData = UserSession.CardManager.CardData(SelectCard)
   Set oProp = CardData.Sections(CardData.Type.Sections.GetByAlias("Properties").ID)
   Set oContrProp = oProp.FindRow("@Name = 'Контрагент'")
   if oContrProp is nothing then
      Set oContrProp = oProp.Rows.AddNew()
      oContrProp.Value("Name") = "Контрагент"
      oContrProp.Value("ParamType") = 11
' ... и т.д. - остальные поля
   end if
next
'Взято с форума forum.idoc.ru

воскресенье, 8 апреля 2012 г.

Об ошибке: 80040543: указанная строка данных не существует

Недавно при написании скрипта на событие сохранения столкнулся со следующей ошибкой:

Ошибка при работе с внутренним документом


Не удалось сохранить изменения
80040543: указанная строка данных не существует


Долго искал и гадал отчего она возникает. Скрипт проходил (вылавливал ошибки мессажбоксами) без ошибок, а уже после обновления карточки вылезала эта ошибка. Оказалась виновата следующая функция поиска строк (здесь используется не тот тип карточки, который был. Просто привел для примера. У меня был карточка типа внутренний документ. Поиск вел по секции Сотрудники. Выбирал сотрудников по полю Type):


CardData.Sections("7A9F0D60-444E-41AF-845E-4F4E94F43A52").FindRows _
("<ConditionGroup><Condition><Field>ApproverRowID</Field><Value>'" & miniRow.value("RowID")& "'</Value></Condition></ConditionGroup>")


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


P.S. Так и осталось загадкой почему так происходило.

четверг, 29 марта 2012 г.

О подключении и работе с DocsVision из VBA приложений

Данный код позволяет подключиться к серверу DocsVision и работать с ним из VBA приложений (Outlook, Word, Excel и т.п.). Чтобы код работал необходимо в редакторе Visual Basic через меню Tools->References подключить следующие библиотеки:
DocsVision 4.5 Card Host
DocsVision 4.5 Navigator
DocsVision 4.5 Object Manager

'Строка подключения к серверу DocsVision. Ее берем из консоли настройки. Лучше, если подключаться будем по named pipe. Тогда в домене нам не потребуется вводить  аутентификационные данные.
Const ConnectString = "\\ServerName\Pipe\DocsVision45\StorageServer"

Dim oSession As UserSession
Dim Manager As New SessionManager
Dim oCard As CardData
Dim Navigator As INavigatorHost2
Dim host As ICardHost


'Подключаемся к серверу
Manager.Connect ConnectString
' Создаем сессию
Set oSession = Manager.CreateSession
' Получаем объект навигатор
Set Navigator = CreateObject("DVNavigator.NavigatorControl")
' Получаем объект CardHost

Set host = Navigator.CreateHost(oSession)


Так как получены основные объекты DocsVision теперь можно с ним работать. Единственное, что недоступно, так это свойства созданной (полученной) карточки документа. То есть нельзя получить и соответственно изменить свойства карточки документа.

понедельник, 26 марта 2012 г.

Получение типа карточки по ИД ее вида

' Функция возвращает тип карточки по ИД вида.
' UserSession - сессия пользователя
' DocsViewID - ИД вида документа
Function GetDocTypeByDocView(UserSession, DocsViewID)
Const ID_TYPESCARD = "{BE14D55D-92B7-4345-AD10-32588981F83D}"
  GetDocTypeByDocView = -1 'Вид документа по-умолчанию. Для возвращаемого значения, если не будет найден вид документа с ИД  DocsViewID
' Получение карточки справочник типов
Set oTypesCard = UserSession.CardManager.DictionaryData(ID_TYPESCARD)
' Получение секции Типы документов справочника типов
Set oSectDocType = oTypesCard.Sections(oTypesCard.Type.AllSections.GetByAlias("DocumentTypes").ID)
' Перебор всех видов документов для поиска необходимого. Можно, наверное, для этого воспользоваться поиском, то есть функцией FindRow.
For Each Row In oSectDocType.AllRows
   If Row.Value("RowID") = DocsViewID Then
      GetDocTypeByDocView = Row.Value("DocumentType")
      Exit Function
   End If
Next
End Function