|
Код VB выполняется в 1С с ошибками, куда копать? | ☑ | ||
---|---|---|---|---|
0
ОператорПК
29.12.14
✎
10:39
|
Здравствуйте.
Заказчик поставил следующую задачу: Организовать в электронном документе 1С (акт об оказании услуг) возможность расписываться исполнителю и ответственному со стороны клиента, само собой подписи должны сохраняться в документе в виде картинок и должна быть возможность вывода подписей на печать. Иными словами приехал сотрудник на объект, выполнил работы – вместо бумаги для подписи акта, расписывается сам в электронной форме документа потом протягивает планшет/телефон и там расписывается представитель заказчика. Саму задачу обсуждать не хотелось бы – особенно ее юридическую сторону и легитимность таких подписей, единственное что скажу – все действия происходят не в России, ни про какие ЭЦП там слыхом не слыхивали и знать не знают что это и зачем. Короче по техническому решению пытаюсь сделать это на обычных формах 1С 8.х. (работать на планшете/телефоне будут через rdp). Для этого на поле документа поместил объект ActiveX с типом значения «Microsoft lnk Picture Control» пытаюсь сохранить данные этого поля в файл (потом загружу его в 1С в реквизит с типом «Хранилище значения» и полученный файл удалю) не выходит каменный цветок…. 1 Украл код С# по моей задаче от сюда http://www.dotnetthoughts.net/using-microsoft-ink-picture-control/ 2 Через вот этот замечательный конвертер http://foxtools.ru/converter перевел код в VB. Адаптировал мега код под себя окончательно пишу в 1С: ScrptCtrl=Новый COMObject("MSScriptControl.ScriptControl"); ScrptCtrl.Language="vbscript"; ScrptCtrl.AddCode("Function GetLord(Pig) |Dim targetFilename As String = ""C:\new1.jpg"" |Dim bytes As var = Pig.Ink.Save(PersistenceFormat.Gif, CompressionMode.Maximum) |Using ms As New MemoryStream(bytes) |Using bmp As New Bitmap(ms) |bmp.Save(targetFilename) |End Using |End Using |End Function"); ScrptCtrl.Run("GetLord",Controls.Element1); Здесь Controls.Element1 – это как раз тот самый элемент формы ActiveX. Код при выполнении выдает ошибку: {Документ.Документ2.Форма.ФормаДокумента1.Форма(140)}: Ошибка при вызове метода контекста (AddCode) ScrptCtrl.AddCode("Function GetLord(Pig) по причине: Произошла исключительная ситуация (Ошибка компиляции Microsoft VBScript): Предполагается наличие окончания инструкции 3 В vb не силен переписал немного «по колхозному» : ScrptCtrl.AddCode("Function GetLord(Pig) |bytes = Pig.Ink.Save() |ms = MemoryStream(bytes) |End Function"); Получаю ошибку: {Документ.Документ2.Форма.ФормаДокумента1.Форма(144)}: Ошибка при вызове метода контекста (Run) ScrptCtrl.Run("GetLord",Controls.Element1); по причине: Произошла исключительная ситуация (Ошибка выполнения Microsoft VBScript): Несоответствие типа: 'MemoryStream' Т.е. VB Не узнает что такое MemoryStream…. Хотя на компе установлен framework 4.5 и в msdn про существование метода MemoryStream черным по белому написано: http://msdn.microsoft.com/ru-ru/library/system.io.memorystream(v=vs.110).aspx . какие будут версии? Чего не хватает для выполнения кода vb? p.s. сори за много букв – сокращал как мог. |
|||
1
IUnknown
29.12.14
✎
10:41
|
у тебя bytes - должно быть целым
|
|||
2
ОператорПК
29.12.14
✎
10:47
|
(1) почему целым? bytes - вполне (судя по msdn) http://msdn.microsoft.com/ru-ru/library/e55f3s5k(v=vs.110).aspx может принимать тип "Массив байтов без знака, из которого создается текущий поток.
" |
|||
3
tridog
29.12.14
✎
10:56
|
(0) Твой MemoryStream - это класс из .Net, напрямую его могут использовать программы, исполняемые поверх инфраструктуры CLR (программы, скомпилирвоанные в MSIL).
Вполне естветственно, что бедный vbscript ничего об этом классе не знает - когда его делали не то что класса MemoryStream, но и всего этого вашего дотнета еще даже в проекте не было. И да, кажется, что записать массив байт в файл вполне можно и без дотнета. |
|||
4
ОператорПК
29.12.14
✎
10:58
|
(3) ок а есть предложение как решить такую задачу?
|
|||
5
IUnknown
29.12.14
✎
11:04
|
а почему тупо не хранить подписи в хранилищезначений?
|
|||
6
ОператорПК
29.12.14
✎
11:07
|
(5) дак именно так и планируется делать, только сперва они должны быть где-то внестись.
|
|||
7
IUnknown
29.12.14
✎
11:12
|
сканеры сейчас сами умеют сканировать в картинку ... ты эту картинку и грузишь в 1С
|
|||
8
ОператорПК
29.12.14
✎
11:15
|
(7) т.е. ты предлагаешь расписываться на листе бумаги потом сканировать это и помечать в документ? тут как раз задача полностью отказать от бумажных носителей.
|
|||
9
tridog
29.12.14
✎
11:43
|
(4) Предложения как сохранить массив байт на диск в vbs? Ставить себе всю эту галиматью конечно не буду, но память подсказывает, что будет как-то так:
Dim theSavedInk() As Byte theSavedInk = ...Ink.Save() // Здесь вызываете Save() от своего контрола-вундервафли // Теперь запишем на диск Open "c:\myfile.jpg" For Output As #1 Write #1, theSavedInk Close #1 P.S. Когда приходить вместо тебя зарплату получать? |
|||
10
Jaap Vduul
29.12.14
✎
11:46
|
А без скриптовой обёртки не работает?
bytes = Pig.Ink.Save(2, 1); А потом в файл через ADODB.Stream... |
|||
11
tridog
29.12.14
✎
11:53
|
(10) Как-ни крути - runtime от ADO сильно тяжелее обвеса от vbs. Т.е. через ADO просто потратим больше ресурсов.
Но на задачах автора пофиг - взглядом разницу заметить будет нельзя. |
|||
12
ОператорПК
29.12.14
✎
12:03
|
(9) я тут зп уже пообещал одному челу который предложил ИМХО гениальное решение - открывать из 1С паинт модально (он утверждает что это возможно, а я этого не знал!!!!!)
Парам=1; WshShell = Новый COMОбъект("WScript.Shell"); WshShell.Run("C:\Windows\notepad.exe", 1, Парам); здесь парам - как раз и отвечает за модальность. так что вставай в очередь за ним. |
|||
13
Jaap Vduul
29.12.14
✎
12:12
|
(11)Что за ерунда?
В vbs вам всё равно тот же самый Stream придётся использовать, т.к. в инструкции Open/Write/Close не поддерживаются. Так что ресурсов потратите ещё больше. |
|||
14
tridog
29.12.14
✎
12:39
|
(12) Не вижу тут модальности - http://msdn.microsoft.com/en-us/library/d5fk67ky(v=vs.84).aspx. Так что давай ка меня первым в очередь?)
(13) Кто не поддерживаются в инструкции Open/Write/Close? |
|||
15
ОператорПК
29.12.14
✎
12:45
|
(14) ну может модальность не работает через "WScript.Shell" но через обычное одноэсовское ЗапуститьПриложение() точно работает - проверено, так что ветвь первенства не твоя, хотя конечно большое спасибо за помощь и проявленный интерес к вопросу.
|
|||
16
tridog
29.12.14
✎
13:23
|
(15) Оно правда откроется модально? Т.е. что выполнение кода на 1Сике прерывается до момента закрытия paint'а - это конечно да, в ЗапуститьПриложение() параметр специальный есть для этого. А вот например свернуть paint можно? А то юзеры свернут, а потом с разворачиванием тупить будут)
P.S. А вообще сделал бы по человечески, без всяких paint'ов) |
|||
17
Garykom
гуру
29.12.14
✎
13:34
|
(16) угу по человечески это прога для планшета/телефона в которой можно расписаться и она картинку в 1С отправит ))
|
|||
18
sapphire
29.12.14
✎
13:45
|
(0) Организовать в электронном документе 1С (акт об оказании услуг) возможность расписываться исполнителю и ответственному со стороны клиента, само собой подписи должны сохраняться в документе в виде картинок и должна быть возможность вывода подписей на печать.
Откуда они картинку подписи брать будут? |
|||
19
ОператорПК
29.12.14
✎
14:11
|
(16) Да свернуть паинт можно, но все равно работать с 1С не получится, по этому будут тупить пока не развернуть обратно,
я тут большой проблемы не вижу. решение с модальным с паинтом - просто как три копейки и как следствие элегантно. кода пишется 10 строк. //Считаем что сразу несколько пользователей //могут делать такую операцию, по этому //чтобы не блокировать один файл делаем каждый //раз новый, а потом его удаляем. ИмяФайла=Новый УникальныйИдентификатор(); НовыйПуть="C:\"+ИмяФайла+".png"; //считаем что на диске уже есть пустой файл который нам нужно скопировать КопироватьФайл("C:\new.png",НовыйПуть); ЗапуститьПриложение(НовыйПуть,,Истина); //Загрузим файл в 1С ВыбранноеИзображение = Новый Картинка(НовыйПуть, Ложь); РеквизитКартинка=Новый ХранилищеЗначения(ВыбранноеИзображение); ЭлементыФормы.ПолеКартинки1.Картинка = РеквизитКартинка.Получить(); //удалим не нужный файл УдалитьФайлы(НовыйПуть); (18) в 1С картинка будет храниться в реквизите с типом "Хранилище значений". |
|||
20
sapphire
29.12.14
✎
14:24
|
(19) С 1С я уже понял.
|
|||
21
ОператорПК
29.12.14
✎
14:25
|
(20) а в чем тогда вопрос?
|
|||
22
karabas11
29.12.14
✎
15:05
|
Нормально работает через аццкую кучу преобразований
InkPictureControl>ADOStream>Файл>ДвоичныеДанные>Картинка http://savepic.ru/6448989.png |
|||
23
ОператорПК
29.12.14
✎
15:30
|
(22) а код не пришлёшь?
|
|||
24
karabas11
29.12.14
✎
15:45
|
(23) типа код пожалуйста
По мотивам (10) и копипасты кода ADOStream из интернета потому что лень набирать ручками Процедура КнопкаВыполнитьНажатие(Кнопка) //Перечисления InkPersistenceFormat = Новый Структура; InkPersistenceFormat.Вставить("IPF_InkSerializedFormat",0); InkPersistenceFormat.Вставить("IPF_Base64InkSerializedFormat",1); InkPersistenceFormat.Вставить("IPF_Gif",2); InkPersistenceFormat.Вставить("IPF_Base64Gif",3); StreamTypeEnum = Новый Структура("adTypeBinary, adTypeText", 1, 2); ConnectModeEnum = Новый Структура( "adModeRead, adModeReadWrite, adModeRecursive, adModeShareDenyNone, |adModeShareDenyRead, adModeShareDenyWrite, adModeShareExclusive, |adModeUnknown, adModeWrite", 1, 3, 4194304, 16, 4, 8, 12, 0, 2); SaveOptionsEnum = Новый Структура("adSaveCreateNotExist, adSaveCreateOverWrite", 1, 2); // Код Данные = ЭтаФорма.ЭлементыФормы.InkPicture.Ink.Save(InkPersistenceFormat.IPF_Gif); СодержимоеМассив = Данные.Выгрузить(); StreamOut = Новый COMОбъект("ADODB.Stream"); StreamOut.Type = StreamTypeEnum.adTypeBinary; StreamOut.Mode = ConnectModeEnum.adModeReadWrite; //Нужны и чтение и запись. ИмяФайла = КаталогВременныхФайлов()+"\temp.gif"; StreamOut.Open(); //Открыли на чтение и запись StreamOut.Write(Данные); StreamOut.SaveToFile(ИмяФайла, SaveOptionsEnum.adSaveCreateOverWrite); //"2" - перезапись файла StreamOut.Close(); ДД = Новый ДвоичныеДанные(ИмяФайла); ЭтаФорма.ЭлементыФормы.ПолеКартинки1.Картинка = Новый Картинка(ДД); КонецПроцедуры |
|||
25
ОператорПК
29.12.14
✎
15:55
|
(24) Круть! Спасибо! Работает!
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |