- Remove From My Forums
-
Question
-
Hello Everyone,
I want to export an 24bit Bitmap «OLE Object» imbedded image from a Table to a file. I’m using Ms Access 2007 and ADO VBA code below. The purpose of the code is to generate a MS Access Application Icon file if one doesn’t already exist.
The code runs fine…it exports the graphic to a file…however when I open it with PaintBrush it’s empty. Thanks in advance for any answers that come my way…Private Sub ExportOLEgraphicToFile
Dim strSQL As String
Dim rstPicture As ADODB.Recordset
Dim PictureStream As ADODB.Stream
Dim strDatabaseFolder As StringOn Error GoTo ErrorMessage
‘Open an ADO Recordset
strDatabaseFolder = Application.CurrentProject.Path & «»
strSQL = «SELECT Graphic FROM T_StoredLogoIcon WHERE ID = 1»
Set rstPicture = New ADODB.Recordset
With rstPicture
.Open strSQL, CurrentProject.Connection
.MoveLast
If .RecordCount = 0 Then
MsgBox «Empty recordset…», vbInformation, «Message»
GoTo CloseRecordSet
End If
.MoveFirst
End WithSet PictureStream = New ADODB.Stream
With PictureStream
.Type = adTypeBinary
.Open
‘MsgBox «ID = » & rstPicture.Fields(«ID»).Value, vbInformation, «Message»
.Write rstPicture.Fields(«Graphic»).Value
.SaveToFile strDatabaseFolder & «Graphic.bmp», adSaveCreateOverWrite
.Close
End WithSet PictureStream = Nothing
MsgBox «Completed…», vbInformation, «Message»
CloseRecordSet:
rstPicture.Close
Set rstPicture = Nothing
Exit SubErrorMessage:
MsgBox «Error in Module M_Code, Test Subroutine. Error description: » & Err.Description, vbInformation, «Error»
End Sub
Answers
-
Good afternoon BrookynDoun,
I found a simple way for approaching to convert to bmp file from CFT file. I succeed on my lab computer. You can try below code.
Dim size As Integer Dim skipSize As Integer skipSize = 78 'skip the ole head information size = rstPicture.Fields("Graphic").ActualSize Dim b() As Byte ReDim b(0 To size - skipSize) Dim j As Integer j = 0 For i = 0 To size - 1 If i > skipSize - 1 Then b(j) = rstPicture.Fields("Graphic").Value(i) j = j + 1 End If Next i With PictureStream .Type = adTypeBinary .Open 'MsgBox "ID = " & rstPicture.Fields("ID").Value, vbInformation, "Message" .Write b .SaveToFile strDatabaseFolder & "Graphic1.bmp", adSaveCreateOverWrite .Close End With
-
Marked as answer by
Monday, August 19, 2013 2:40 PM
-
Marked as answer by
See more:
I wrote this code in vb6 , it ‘s work
But it ‘s error on ASP
How do i resolve this problem.
PS:please observe the position wich i made underline
Set Stream = Server.CreateObject("adodb.Stream")
Set rx = Server.CreateObject("adodb.recordset")<br> rx.open "select top 1 Picturefield from databasePicture",cn,3,3 if not rx.eof then Stream.open<br> <big>Stream.Write rx("Picturefield") '<-- This line generate err-->ADODB.Stream error '800a0bb9' <br>If </br></big>fso.FileExists(px & filename ) Then 'check old file exists!<br> fso.DeleteFile px & filename 'delete old file<br> end if Stream.SaveToFile px & filename 'save bin to file<br> Stream.Close<br> Set Stream = Nothing <br> End if</br></br></br></br></br></br></br>
Updated 13-Dec-10 14:54pm
Comments
You left out the most important part of your question. WHAT’S THE ERROR?!
Update the question with error.
01.08.11 — 07:09
Всем привет!
Перекодирую текст с помощью Adodb.Stream. 1С вылетает на методе Stream.WriteText(Text). С короткой строкой проблем нет, а у меня Файл текстовый 1,5Мб.
Есть тема в архиве: utf8
Делаю все в точности.
Попробовал другой вариант. Сначала записать файл, а потом перекодировать. Тоже самое.
Ребят, подскажите пожалуйста, где копать?
1 — 01.08.11 — 07:22
Мне помогло следующее:
Текст = СоздатьОбъект(«Текст»);
Текст.ДобавитьСтроку(Stream.readText());
2 — 01.08.11 — 07:28
Спасибо, Кристина!
Я вот только думал в этом направлении, чтобы как-то по строке перекодировать.
3 — 01.08.11 — 07:35
(2) Там тоже получится одна длинная строка, но её потом можно разбить построчно и т.п.
4 — 01.08.11 — 07:54
Сейчас пробую. Напишу результат. То есть если я правильно понял, после
Текст = СоздатьОбъект(«Текст»);
Текст.ДобавитьСтроку(Stream.readText());
Должен заработать:
Stream.WriteText(Текст);
Правильно?
5 — 01.08.11 — 07:56
Stream.WriteText(Текст); —>>> Это вообще не надо.
Текст запишется в одинэсовский объект «Текст». С ним затем и работай.
6 — 01.08.11 — 08:00
Так, но потом Текст.Записать() и где кодировка? Кодировка будет стандартной DOS или Windows. Правильно? А мне надо utf-8
7 — 01.08.11 — 08:00
Из моей обработке по загрузке файла:
[1с]
Если НужнаПерекодировка = 1 Тогда
// Перекодировка.
Стрим = СоздатьОбъект(«ADODB.Stream»);
Стрим.Type = 2;
Стрим.charset = «windows-1251»;
Стрим.Open();
Стрим.LoadFromFile(СокрЛП(ВыбФайл));
Стрим.charset = «utf-8»;
ВремТекст = СоздатьОбъект(«Текст»);
ВремТекст.ДобавитьСтроку(Стрим.readText());
Стрим.close();
Стрим = «»;
КонецЕсли;
// Здесь у меня разбивается на строки помельче, идет замена некоторых символов и т.п. На выходе получаем многострочный текст, который уже можно записать в файл.
Текст = ОбработатьТекст(ВремТекст);
[/1с]
8 — 01.08.11 — 08:17
Стрим = СоздатьОбъект(«ADODB.Stream»);
Стрим.Type = 2;
Стрим.charset = «windows-1251»;
Стрим.Open();
Стрим.LoadFromFile(СокрЛП(ВыбФайл));
Стрим.charset = «utf-8»;
Пока Стрим.EOS=0 Цикл
Сообщить(Стрим.readText(-2));
КонецЦикла;
Стрим.close();
9 — 01.08.11 — 08:23
(8) Спасибо
10 — 01.08.11 — 08:35
Stream = СоздатьОбъект(«Adodb.Stream»);
Stream.Charset=»windows-1251″;
Stream.Type = 2;
Stream.Open();
Stream.LoadFromFile(Файлtxt);
ВремТекст = СоздатьОбъект(«Текст»);
ВремТекст.ДобавитьСтроку(Stream.ReadText());
Stream.Close();
Текст.Записать(Файл2);
И после этого Файл2 совсем не в utf-8? Что не так?
11 — 01.08.11 — 08:36
*пардон в конце ВремТекст.Записать(Файл2);
12 — 01.08.11 — 08:37
(10) откуда взялся объект Текст?
13 — 01.08.11 — 08:37
(10) ты чё к этому Тексту привязался? делаешь через Stream — ну так и делай. Текст не поддерживает unicode
14 — 01.08.11 — 08:38
а где смена чарсета (а по хорошему и позиционирование на начало) ?
15 — 01.08.11 — 08:38
Стрим = СоздатьОбъект(«ADODB.Stream»);
Стрим.Type = 2;
Стрим.charset = «windows-1251»;
Стрим.Open();
Стрим.LoadFromFile(СокрЛП(ВыбФайл));
Стрим.charset = «utf-8»;
ВремТекст = СоздатьОбъект(«Текст»);
Пока Стрим.EOS=0 Цикл
ВремТекст.ДобавитьСтроку(Стрим.readText(-2));
КонецЦикла;
Стрим.close();
ВремТекст.Записать(Файл2);
16 — 01.08.11 — 08:38
+(13) а, хотя тут utf-8, может и взлететь
17 — 01.08.11 — 08:38
(13) утф8 вполне «поддерживает» в нем практически не присутствует симв(0)
18 — 01.08.11 — 08:38
(15) ему нужно записать в ЮТФ, а не прочитать
19 — 01.08.11 — 08:40
(17) да, понял уже. но всё равно изврат. Stream надо юзать и для чтения, и для записи
20 — 01.08.11 — 08:44
Проблема в том, что Stream при записи Stream.WriteText(Text) 1С вылетает и все. Никаких ошибок, просто закрывается. В чем причина неясно
21 — 01.08.11 — 08:45
77 имеет ограничение на размер строки, где-то около 800 килобайт.
по этому поточные операции должны идти вне контеста 1с
22 — 01.08.11 — 08:46
(21)+ то есть переменная хранящая текст должны быть НЕ 1с
23 — 01.08.11 — 08:47
Как это реализовать?
24 — 01.08.11 — 08:51
(23) COM объект создавать не в 1с, или загружать кусками.
кроме того в 1с в строковой переменной есть запрещенные символы, по этому если файл их содержит они просто исчезнут из результата….
используй ADO для текстовых файлов и конверти средствами TSQL
25 — 01.08.11 — 08:53
(24)Спасибо, буду пробовать.
26 — 01.08.11 — 08:53
И вообще, всем спасибо!
27 — 01.08.11 — 09:06
Привожу выдержку и описания компоненты BinFiles.dll
Непосредственному хранению двоичных данных в длинных строках 1С Предприятие 7.7 мешают
следующие обстоятельства:
1. 1С Предприятие «не признаёт» символ с кодом 0 в строках.
2. Большинство символов с кодами 1-32 в длинной строке при осуществлении операции
«Тестирование и исправление ИБ» будут восприняты как ошибка.
3. При сохранении длинной строки 1С Предприятие обрезает конечные пустые символы
(пробел, перевод строки и т.п.), что для двоичных данных недопустимо.
4. Размер длинной строки ограничен значением ~780Кб.
28 — 01.08.11 — 09:12
(15) а после этого все равно файл то не utf-8
29 — 01.08.11 — 09:17
30 — 01.08.11 — 09:47
(29) спасибо, но это не то, там только кирилица и цифры переводятся в utf
31 — 01.08.11 — 09:57
32 — 01.08.11 — 10:10
Автор тебе файл перекодировать ?
33 — 01.08.11 — 10:18
(32)Угу.
smaharbA
34 — 01.08.11 — 11:26
//*******************************************
Процедура Сформировать()
Перем Имя,Путь;
Байт=255;
Если ФС.ВыбратьФайл(0,Имя,Путь,»»,»Файлы|*»,»*»)=0 Тогда
Возврат;
КонецЕсли;
СтримВход=СоздатьОбъект(«ADODB.Stream»);
СтримВход.Type=2;
СтримВход.charset=»windows-1251″;
СтримВход.Open();
СтримВход.LoadFromFile(Путь+Имя);
СтримВыход=СоздатьОбъект(«ADODB.Stream»);
СтримВыход.Type=2;
СтримВыход.charset=»utf-8″;
СтримВыход.LineSeparator=-1;
СтримВыход.Open();
Всего=СтримВход.size;
Пока СтримВход.EOS=0 Цикл
СтримВыход.WriteText(СтримВход.ReadText(Байт),?(Байт=-2,1,0));
Состояние(«» + Формат(100 * СтримВход.position/Всего,»Ч(0)5.2″)+»%»);
КонецЦикла;
СтримВыход.SaveToFile(Путь+Имя+».utf8″,2);
КонецПроцедуры
Предложите, как улучшить StudyLib
(Для жалоб на нарушения авторских прав, используйте
другую форму
)
Ваш е-мэйл
Заполните, если хотите получить ответ
Оцените наш проект
1
2
3
4
5
- Remove From My Forums
-
Question
-
I have an older VB application in which I open f.ex. an Excel file.
Dim oFileStream As ADODB.Stream
…
With oFileStream
.Type = adTypeText
‘.Mode = adModeRead
.Open
.LoadFromFile sPathFile
…Everything’s running well. Only if the Excel file is opened by Excel at the same time I got the error «File could not be opened.» (3002) in the LoadFromFile-line. If I uncomment the mode property, I got the error «Operation is not allowed
in this context.» on the LoadFromFile command. The file should be opened readonly.Any thoughts?
Tx,
Patrick
-
Moved by
Monday, February 16, 2015 10:11 AM
VB6 is not supported
-
Moved by
Answers
-
-
Edited by
Rbie
Tuesday, February 10, 2015 8:45 AM -
Marked as answer by
Carl Cai
Monday, February 16, 2015 10:11 AM
-
Edited by
Перейти к содержимому раздела
Серый форум
разработка скриптов
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
1 2012-11-17 06:41:12 (изменено: yuriy2000, 2012-11-17 19:12:54)
- yuriy2000
- Участник
- Неактивен
- Рейтинг : [0|0]
Тема: VBS: Глюк ADODB.Stream?
Случайно столкнулся с неприятным глюком при использовании ADODB.Stream:
для конвертации из кодировки UTF-8 в Windows-1251 использую функцию из копилки идей
При чтении из файла в кодировке UTF-8, содержащего символы определяющие денежные единицы, например символ Йены (код в таблице Unicode U+00A5) или анг.фунта (U+00A3), при условии что не установлена опция On Error Resume Next получаем ошибку
Ошибка выполнения Microsoft VBScript: Недопустимый вызов или аргумент процедуры
Точнее ошибка возникает не при чтении, а при дальнейшем использовании строки считанной из файла.
Я написал тестовый пример (см. ниже), который создает строки в формате UTF-8, содержащие символы C2A0 … C2BF (символы Unicode U+00A0…U+00BF) и потом их конвертирует в Win-1251 — в результате получается, что создаются не пустыми лишь некоторые файлы.
U+00A0 U+00A4 U+00A6 U+00A7 U+00A9 U+00AB U+00AC U+00AD U+00AE U+00B0 U+00B1 U+00B5 U+00B6 U+00B7 U+00BB.
Остальные создаются пустыми.
Парадокс: Если конвертировать UTF-8 в кодовую таблицу 866, то таких проблем не возникает. Некоторые символы просто не перекодируются и всё — т.е. файлы в 866-кодировке в тестовом примере получаются размером 2 либо 3 байта.
Кто-нибудь из гуру может прокомментировать такое странное поведение ADODB.Stream?
PS: при использовании аналогичной функции из копилки с перекодировкой файла таких проблем не возникает
Option Explicit
Dim i
On Error Resume Next
for i=&HA0 to &HBF
test i
next 'i
On Error GoTo 0
WScript.Quit
sub test(sAsc)
Dim sBuf, oFileOut
Dim oFSO : Set oFSO = CreateObject("Scripting.FileSystemObject")
sBuf=chr(&HC2) & chr(sAsc) '
set oFileOut = oFSO.CreateTextFile(hex(sAsc) & ".txt",True)
'oFileOut.WriteLine StrConv(sBuf,"cp866","UTF-8")
oFileOut.WriteLine StrConv(sBuf,"windows-1251","UTF-8")
oFileOut.Close
end sub
Function StrConv(Text,SourceCharset,DestCharset)
Dim Stream
Set Stream = CreateObject("ADODB.Stream")
Stream.Type = 2
Stream.Mode = 3
Stream.Open
Stream.Charset = SourceCharset
Stream.WriteText Text
Stream.Position = 0
Stream.Charset = DestCharset
StrConv = Stream.ReadText
End Function
2 Ответ от BeS Yara 2012-12-04 10:54:06
- BeS Yara
- Разработчик
- Неактивен
- Рейтинг : [2|0]
Re: VBS: Глюк ADODB.Stream?
Проблема не в ADO.DB, проблема в FSO — ошибка возникает не при работе со строкой, а при попытке её записать в файл методом WriteLine(достаточно запустить скрипт в отладчике).
Соответственно файл уже создан(пустой), записать не удалось. А так как на ошибки забиваем — идём дальше и получаем толпу пустых файлов. Возможно какой-то баг FSO при попытке писать UTF-8 в открытый как ASCII файл.
yuriy2000 пишет:
Я написал тестовый пример (см. ниже), который создает строки в формате UTF-8, содержащие символы C2A0 … C2BF (символы Unicode U+00A0…U+00BF) и потом их конвертирует в Win-1251
Вообще-то, пример делает наоборот
Чтобы конвертировать из UTF в cp1251 нужно аргументы поменять местами
oFileOut.WriteLine StrConv(sBuf,"UTF-8","windows-1251")
3 Ответ от yuriy2000 2012-12-05 05:05:27
- yuriy2000
- Участник
- Неактивен
- Рейтинг : [0|0]
Re: VBS: Глюк ADODB.Stream?
касательно использования StrConv(sBuf,»UTF-8″,»windows-1251″) — дискуссия была здесь:
http://forum.script-coding.com/viewtopic.php?id=1179
4 Ответ от BeS Yara 2012-12-05 11:01:20
- BeS Yara
- Разработчик
- Неактивен
- Рейтинг : [2|0]
Re: VBS: Глюк ADODB.Stream?
Действительно…
Правда в свете этого:
Charset Property (ADO):Sets or returns a String value that specifies the character set into which the contents of the Stream will be translated. The default value is Unicode.
а также приведённого в MSDN примера, всё выглядит не очень логично(для меня), но на тестовом примере(чтение строки из файла в UTF-8, StrConv, запись в ASCII файл) это подтвердилось(похоже я в корне неверно понимаю работу с ado.stream ).
Однако, в Вашем случае если ADO и виноват, то лишь косвенно — ошибка возникает всё-таки после того как ADO своё отработал.
5 Ответ от yuriy2000 2012-12-05 20:25:11
- yuriy2000
- Участник
- Неактивен
- Рейтинг : [0|0]
Re: VBS: Глюк ADODB.Stream?
BeS Yara пишет:
Действительно…
…..
Однако, в Вашем случае если ADO и виноват, то лишь косвенно — ошибка возникает всё-таки после того как ADO своё отработал.
Возможно, что проблема и не ado.stream , но всё-таки что-то с ним не так, ведь если перекодировать в cp866, то проблем не возникает…
6 Ответ от BeS Yara 2012-12-06 13:04:53
- BeS Yara
- Разработчик
- Неактивен
- Рейтинг : [2|0]
Re: VBS: Глюк ADODB.Stream?
Если посмотреть ASCII-код символов на выходе из потока, то можно обратить внимание на характерный факт: «ненулевые» файлы возникают для символов для которых vbscript выдаёт одинаковый код и через Asc и через AscW. Для части символов коды совпадают, для остальных Asc=63(вопросительный знак), и ошибка метода .WriteLine.
Такое впечатление, что проблемы нет только для символов имеющих «синоним» или дубль в US-ASCII. Навеяно вики(ASCII-Национальные варианты ASCII, первый абзац), но обосновать не могу — не по всем работающим символам в статье есть упоминание.
Полагаю, что пример(по работе напрямую с файлом) работает без проблем по той причине, что ADO.Stream читает и пишет файлы не посимвольно, а побайтово. А потому вся работа с кодировками выполняется в нём без лишних «прокладок».
В Вашем случае прибавляется vbscript со своими тараканами.
Всё ниже сказанное — великое колдунство, которое я сам до конца не понял(какая-то идея под коркой шевелиться, но сформулировать не получается).:)
Если заменить:
oFileOut.WriteLine StrConv(sBuf,"windows-1251","UTF-8")
на
oFileOut.WriteLine Chr(AscW(StrConv(sBuf,"windows-1251","UTF-8")))
то ошибка не возникает, файлы пишутся все.
P.S. буду премного благодарен, если найдётся голова, которая мне популярно пояснит что же я сделал и почему запись 161-го(например) символа в рассматриваемом скрипте(изначальном) даёт ошибку, а этот код нет:
option explicit
Dim f : set f = CreateObject("Scripting.FileSystemObject").CreateTextFile("ascii.txt",True)
f.Write Chr(161)
P.P.S. возможно таки ADO тут «при чём»…
7 Ответ от YMP 2012-12-06 14:03:14
- YMP
- Разработчик
- Неактивен
Re: VBS: Глюк ADODB.Stream?
yuriy2000 пишет:
PS: при использовании аналогичной функции из копилки с перекодировкой файла таких проблем не возникает
Но эта функция вам не подходит? Тогда поясните, в чём конкретно ваша задача заключается, что вы пытаетесь сделать?
8 Ответ от yuriy2000 2012-12-06 18:09:48
- yuriy2000
- Участник
- Неактивен
- Рейтинг : [0|0]
Re: VBS: Глюк ADODB.Stream?
YMP пишет:
yuriy2000 пишет:
PS: при использовании аналогичной функции из копилки с перекодировкой файла таких проблем не возникает
Но эта функция вам не подходит? Тогда поясните, в чём конкретно ваша задача заключается, что вы пытаетесь сделать?
Да, эта функция из копилки (с конвертацией всего файла за один проход) решила мои проблемы, в конкретном случае…, но дело в том, что хотелось бы конвертировать строки в памяти. В будущем…
Может быть совместными усилиями найдем решение проблемы с этой StrConv.
9 Ответ от YMP 2012-12-06 20:39:33
- YMP
- Разработчик
- Неактивен
Re: VBS: Глюк ADODB.Stream?
yuriy2000 пишет:
Я написал тестовый пример (см. ниже), который создает строки в формате UTF-8
Тогда вам нужно использовать функцию ChrB. У вас в примере создаётся строка из двух юникодных двухбайтных символов (UTF-16), а не один двухбайтный символ UTF-8.
Если читать файл UTF-8 через FSO как ANSI, то во время чтения происходит конвертация в UTF-16, поскольку таков формат строк в VBScript. Конвертация пойдёт по таблице 1251 и в переменной окажется нечитаемый набор символов.
Восстановить строку можно записью из переменной в Stream, кодировка которого 1251. При этом произойдёт конвертация уже из Юникода по той же 1251 таблице, т.е. процесс, обратный тому, который привёл к порче строки. После этого меняем кодировку Stream на UTF-8, чтобы она соответствовала содержимому и читаем снова в переменную, при этом происходит конвертация в Юникод, но уже по правильной таблице UTF-8. В итоге имеем в переменной читаемый текст в UTF-16.
При попытке сохранить его через FSO в файл в кодировке 1251 проблема возникает, судя по всему, из-за символов, отсутствующих в целевой кодовой странице, т.е. тех, которые были бы заменены на знак вопроса. Может, забота о том, чтобы у пользователя информация не терялась.
10 Ответ от YMP 2012-12-06 21:58:18
- YMP
- Разработчик
- Неактивен
Re: VBS: Глюк ADODB.Stream?
Если всё же нужно записать такой текст через FSO в файл в 1251, пусть даже с заменой отсутствующих в ней символов на «?», то можно предварительно сделать так:
sBuf = StrConv(sBuf,"windows-1251","windows-1251")
Получим ту же строку UTF-16, но где неродные для 1251 символы уже заменены на знаки вопроса, так что FSO не будет протестовать.
11 Ответ от yuriy2000 2012-12-06 22:47:18
- yuriy2000
- Участник
- Неактивен
- Рейтинг : [0|0]
Re: VBS: Глюк ADODB.Stream?
YMP пишет:
sBuf = StrConv(sBuf,"windows-1251","windows-1251")
Хм. Без комментариев похоже на шаманство. Но ведь это действительно работает!
Кто бы мог подумать…
Огромное Спасибо!!!
Сообщения 11
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться