How to store and then display picture using vb6 and oracle? - oracle

'code to load picture into database table
Private Function GetPic()
Dim filelen As Long
Dim numlock As Integer
Dim leftover As Long
Const blocksize = 100000
Dim pic As String
Dim bytedata() As Byte
Dim sfile As Integer
sql = "select PICS from student_record_database " //empty field with no pictures
RES.Open sql, CON, adOpenDynamic, adLockOptimistic
sfile = App.Path & "/mypic/Book1.xls" //error : type mismatch
Open sfile For Binary Access Read As #1
filelen = LOF(sfile)
If filelen = 0 Then
Close sfile
MsgBox ("empty or not found")
Else
numlock = filelen / blocksize
leftover = filelen Mod blocksize
ReDim bytedata(leftover)
Get sfile, , bytedata()
RES(1).AppendChunk bytedata()
ReDim bytedata(blocksize)
For i = 1 To numlock
Get sfile, , bytedata()
RES(1).AppendChunk bytedata()
Next i
RES.Update
Close sfile
End If
End Function
'code to display picture in picture box from table
Private Function ShowPic()
Dim bytedata() As Byte
Dim file As String
Dim filelen As Long
Dim numlock As Integer
Dim leftover As Long
Const blocksize = 100000
file = App.Path & "\image1.jpeg"
Open file For Binary As #1
numlock = filelen / blocksize
leftover = filelen Mod blocksize
bytedata() = RES(1).GetChunk(leftover)
Put file, , bytedata()
For i = 1 To numlock
bytedata() = RES(1).GetChunk(blocksize)
Put file, , bytedata()
Next i
Close file
End Function
Here is my full code to insert pictures using vb in an oracle table database.
Next I display those pictures in picture box of vb application as per their records, but it is showing an error of "type mismatch" and picture is not shown in picture box.

you declared sFile as an integer, but are trying to load a string in it
Dim sFile as string
sfile = App.Path & "/mypic/Book1.xls"

Related

Export pictures from excel file into jpg using VBA

I have an Excel file which includes pictures in column B and I want like to export them into several files as .jpg (or any other picture file format). The name of the file should be generated from text in column A. I tried following VBA macro:
Private Sub CommandButton1_Click()
Dim oTxt As Object
For Each cell In Ark1.Range("A1:A" & Ark1.UsedRange.Rows.Count)
' you can change the sheet1 to your own choice
saveText = cell.Text
Open "H:\Webshop_Zpider\Strukturbildene\" & saveText & ".jpg" For Output As #1
Print #1, cell.Offset(0, 1).text
Close #1
Next cell
End Sub
The result is that it generates files (jpg), without any content. I assume the line Print #1, cell.Offset(0, 1).text. is wrong.
I don't know what I need to change it into, cell.Offset(0, 1).pix?
Can anybody help me? Thanks!
If i remember correctly, you need to use the "Shapes" property of your sheet.
Each Shape object has a TopLeftCell and BottomRightCell attributes that tell you the position of the image.
Here's a piece of code i used a while ago, roughly adapted to your needs. I don't remember the specifics about all those ChartObjects and whatnot, but here it is:
For Each oShape In ActiveSheet.Shapes
strImageName = ActiveSheet.Cells(oShape.TopLeftCell.Row, 1).Value
oShape.Select
'Picture format initialization
Selection.ShapeRange.PictureFormat.Contrast = 0.5: Selection.ShapeRange.PictureFormat.Brightness = 0.5: Selection.ShapeRange.PictureFormat.ColorType = msoPictureAutomatic: Selection.ShapeRange.PictureFormat.TransparentBackground = msoFalse: Selection.ShapeRange.Fill.Visible = msoFalse: Selection.ShapeRange.Line.Visible = msoFalse: Selection.ShapeRange.Rotation = 0#: Selection.ShapeRange.PictureFormat.CropLeft = 0#: Selection.ShapeRange.PictureFormat.CropRight = 0#: Selection.ShapeRange.PictureFormat.CropTop = 0#: Selection.ShapeRange.PictureFormat.CropBottom = 0#: Selection.ShapeRange.ScaleHeight 1#, msoTrue, msoScaleFromTopLeft: Selection.ShapeRange.ScaleWidth 1#, msoTrue, msoScaleFromTopLeft
'/Picture format initialization
Application.Selection.CopyPicture
Set oDia = ActiveSheet.ChartObjects.Add(0, 0, oShape.Width, oShape.Height)
Set oChartArea = oDia.Chart
oDia.Activate
With oChartArea
.ChartArea.Select
.Paste
.Export ("H:\Webshop_Zpider\Strukturbildene\" & strImageName & ".jpg")
End With
oDia.Delete 'oChartArea.Delete
Next
This code:
Option Explicit
Sub ExportMyPicture()
Dim MyChart As String, MyPicture As String
Dim PicWidth As Long, PicHeight As Long
Application.ScreenUpdating = False
On Error GoTo Finish
MyPicture = Selection.Name
With Selection
PicHeight = .ShapeRange.Height
PicWidth = .ShapeRange.Width
End With
Charts.Add
ActiveChart.Location Where:=xlLocationAsObject, Name:="Sheet1"
Selection.Border.LineStyle = 0
MyChart = Selection.Name & " " & Split(ActiveChart.Name, " ")(2)
With ActiveSheet
With .Shapes(MyChart)
.Width = PicWidth
.Height = PicHeight
End With
.Shapes(MyPicture).Copy
With ActiveChart
.ChartArea.Select
.Paste
End With
.ChartObjects(1).Chart.Export Filename:="MyPic.jpg", FilterName:="jpg"
.Shapes(MyChart).Cut
End With
Application.ScreenUpdating = True
Exit Sub
Finish:
MsgBox "You must select a picture"
End Sub
was copied directly from here, and works beautifully for the cases I tested.
''' Set Range you want to export to the folder
Workbooks("your workbook name").Sheets("yoursheet name").Select
Dim rgExp As Range: Set rgExp = Range("A1:H31")
''' Copy range as picture onto Clipboard
rgExp.CopyPicture Appearance:=xlScreen, Format:=xlBitmap
''' Create an empty chart with exact size of range copied
With ActiveSheet.ChartObjects.Add(Left:=rgExp.Left, Top:=rgExp.Top, _
Width:=rgExp.Width, Height:=rgExp.Height)
.Name = "ChartVolumeMetricsDevEXPORT"
.Activate
End With
''' Paste into chart area, export to file, delete chart.
ActiveChart.Paste
ActiveSheet.ChartObjects("ChartVolumeMetricsDevEXPORT").Chart.Export "C:\ExportmyChart.jpg"
ActiveSheet.ChartObjects("ChartVolumeMetricsDevEXPORT").Delete
Dim filepath as string
Sheets("Sheet 1").ChartObjects("Chart 1").Chart.Export filepath & "Name.jpg"
Slimmed down the code to the absolute minimum if needed.
New versions of excel have made old answers obsolete. It took a long time to make this, but it does a pretty good job. Note that the maximum image size is limited and the aspect ratio is ever so slightly off, as I was not able to perfectly optimize the reshaping math. Note that I've named one of my worksheets wsTMP, you can replace it with Sheet1 or the like. Takes about 1 second to print the screenshot to target path.
Option Explicit
Private Declare PtrSafe Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Sub weGucciFam()
Dim tmp As Variant, str As String, h As Double, w As Double
Application.PrintCommunication = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
If Application.StatusBar = False Then Application.StatusBar = "EVENTS DISABLED"
keybd_event vbKeyMenu, 0, 0, 0 'these do just active window
keybd_event vbKeySnapshot, 0, 0, 0
keybd_event vbKeySnapshot, 0, 2, 0
keybd_event vbKeyMenu, 0, 2, 0 'sendkeys alt+printscreen doesn't work
wsTMP.Paste
DoEvents
Const dw As Double = 1186.56
Const dh As Double = 755.28
str = "C:\Users\YOURUSERNAMEHERE\Desktop\Screenshot.jpeg"
w = wsTMP.Shapes(1).Width
h = wsTMP.Shapes(1).Height
Application.DisplayAlerts = False
Set tmp = Charts.Add
On Error Resume Next
With tmp
.PageSetup.PaperSize = xlPaper11x17
.PageSetup.TopMargin = IIf(w > dw, dh - dw * h / w, dh - h) + 28
.PageSetup.BottomMargin = 0
.PageSetup.RightMargin = IIf(h > dh, dw - dh * w / h, dw - w) + 36
.PageSetup.LeftMargin = 0
.PageSetup.HeaderMargin = 0
.PageSetup.FooterMargin = 0
.SeriesCollection(1).Delete
DoEvents
.Paste
DoEvents
.Export Filename:=str, Filtername:="jpeg"
.Delete
End With
On Error GoTo 0
Do Until wsTMP.Shapes.Count < 1
wsTMP.Shapes(1).Delete
Loop
Application.PrintCommunication = True
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.StatusBar = False
End Sub
Thanks for the ideas! I used the above ideas to make a macro to do a bulk file conversion--convert every file of one format in a folder to another format.
This code requires a sheet with cells named "FilePath" (which must end in a "\"), "StartExt" (original file extension), and "EndExt" (desired file extension). Warning: it doesn't ask for confirmation before replacing existing files with the same name and extension.
Private Sub CommandButton1_Click()
Dim path As String
Dim pathExt As String
Dim file As String
Dim oldExt As String
Dim newExt As String
Dim newFile As String
Dim shp As Picture
Dim chrt As ChartObject
Dim chrtArea As Chart
Application.ScreenUpdating = False
Application.DisplayAlerts = False
'Get settings entered by user
path = Range("FilePath")
oldExt = Range("StartExt")
pathExt = path & "*." & oldExt
newExt = Range("EndExt")
file = Dir(pathExt)
Do While Not file = "" 'cycle through all images in folder of selected format
Set shp = ActiveSheet.Pictures.Insert(path & file) 'Import image
newFile = Replace(file, "." & oldExt, "." & newExt) 'Determine new file name
Set chrt = ActiveSheet.ChartObjects.Add(0, 0, shp.Width, shp.Height) 'Create blank chart for embedding image
Set chrtArea = chrt.Chart
shp.CopyPicture 'Copy image to clipboard
With chrtArea 'Paste image to chart, then export
.ChartArea.Select
.Paste
.Export (path & newFile)
End With
chrt.Delete 'Delete chart
shp.Delete 'Delete imported image
file = Dir 'Advance to next file
Loop
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Here is another cool way to do it- using en external viewer that accepts command line switches (IrfanView in this case) :
* I based the loop on what Michal Krzych has written above.
Sub ExportPicturesToFiles()
Const saveSceenshotTo As String = "C:\temp\"
Const pictureFormat As String = ".jpg"
Dim pic As Shape
Dim sFileName As String
Dim i As Long
i = 1
For Each pic In ActiveSheet.Shapes
pic.Copy
sFileName = saveSceenshotTo & Range("A" & i).Text & pictureFormat
Call ExportPicWithIfran(sFileName)
i = i + 1
Next
End Sub
Public Sub ExportPicWithIfran(sSaveAsPath As String)
Const sIfranPath As String = "C:\Program Files\IrfanView\i_view32.exe"
Dim sRunIfran As String
sRunIfran = sIfranPath & " /clippaste /convert=" & _
sSaveAsPath & " /killmesoftly"
' Shell is no good here. If you have more than 1 pic, it will
' mess things up (pics will over run other pics, becuase Shell does
' not make vba wait for the script to finish).
' Shell sRunIfran, vbHide
' Correct way (it will now wait for the batch to finish):
call MyShell(sRunIfran )
End Sub
Edit:
Private Sub MyShell(strShell As String)
' based on:
' http://stackoverflow.com/questions/15951837/excel-vba-wait-for-shell-command-to-complete
' by Nate Hekman
Dim wsh As Object
Dim waitOnReturn As Boolean:
Dim windowStyle As VbAppWinStyle
Set wsh = VBA.CreateObject("WScript.Shell")
waitOnReturn = True
windowStyle = vbHide
wsh.Run strShell, windowStyle, waitOnReturn
End Sub

How to deal with appendchunk and getchunk methods?

Private Function ShowPic()
Dim bytedata() As Byte
Dim destfile As Integer
Dim file As String
Dim filelen As Long
Dim numlock As Double
Dim leftover As Long
Const blocksize = 100000
file = App.Path & "\image1.jpeg"
destfile = FreeFile
Open file For Binary Access Write As destfile
filelen = RES(0).ActualSize
numlock = filelen / blocksize
leftover = filelen Mod blocksize
bytedata() = RES(0).GetChunk(leftover)
Put destfile, , bytedata()
For i = 1 To numlock
bytedata() = RES(0).GetChunk(blocksize)
Put destfile, , bytedata()
Next i
Close destfile
Picture1.Picture = LoadPicture(App.Path & "\image1.jpeg")
RES.Close
End Function
This is my code to fetch image which is stored in database and display into the picture box,whenever I run the code error occur like:Item cannot found in corresponding ordinal or name

How to save picture in BLOB format?

I did code for procedure that prompts for a .jpeg file, converts that file to a Byte array, and saves the Byte Array to the table using the Append chunk method.
Another procedure retrieves the picture image from the table using the GetChunk method, converts the data to a file and displays that file in the Picture box.
Now, my question is that how do I save that image displayed in picture box into the database, so that I can perform operations like: add/update etc.
I did something like this way:
Private Sub CmdSave_Click()
if(cmbRNO=" ") then
sql = "INSERT INTO STUDENT_RECORD_DATABASE(ROLLNO,PICS)"
sql = sql + "VALUES(" & RNo & ","& picture1.picture &")"
Set RES = CON.Execute(sql)
Else
sql = "UPDATE STUDENT_RECORD_DATABASE SET "
sql = sql + "ROLLNO= " & Val(CmbRNO) & ","
sql = sql + "PICS=" & Picture1.Picture & " "
sql = sql + "WHERE ROLLNO= " & Val(CmbRNO) & ""
Set RES = CON.Execute(sql)
End If
End Sub
<code for appendchunk method>
Public Sub Command1_Click()
Dim PictBmp As String
Dim ByteData() As Byte 'Byte array for Blob data.
Dim SourceFile As Integer
' Open the BlobTable table.
strSQL = "Select ID, DOC from LOB_TABLE WHERE ID = 1"
Set Rs = New ADODB.Recordset
Rs.CursorType = adOpenKeyset
Rs.LockType = adLockOptimistic
Rs.Open strSQL, Cn
' Retrieve the picture and update the record.
CommonDialog1.Filter = "(*.jpeg)|*.jpeg"
CommonDialog1.ShowOpen
PictBmp = CommonDialog1.FileName
' Save Picture image to the table column.
SourceFile = FreeFile
Open PictBmp For Binary Access Read As SourceFile
FileLength = LOF(SourceFile) ' Get the length of the file.
If FileLength = 0 Then
Close SourceFile
MsgBox PictBmp & " empty or not found."
Exit Sub
Else
Numblocks = FileLength / BlockSize
LeftOver = FileLength Mod BlockSize
ReDim ByteData(LeftOver)
Get SourceFile, , ByteData()
Rs(1).AppendChunk ByteData()
ReDim ByteData(BlockSize)
For i = 1 To Numblocks
Get SourceFile, , ByteData()
Rs(1).AppendChunk ByteData()
Next i
Rs.Update 'Commit the new data.
Close SourceFile
End If
End Sub
While trying to save image to specific record, run-time error occurs:
inconsistent datatype,expected BLOB got number
Where as:
?sql
UPDATE STUDENT_RECORD_DATABASE SET ROLLNO= 132,PICS=688195876 WHERE ROLLNO= 132

VB 6 + Capture text from file and copy it to form window

The following VB 6 code saves text from the textBox in the form GUI to file.txt (By the click on the button)
How to do the reverse option – copy/capture file text (file.txt) , and passed it on the textBox in the form GUI , I will happy to get real example
remark - (before passed need to clear the form window from any text )
Private Sub save_Click()
saves = (Form1.Caption)
FCO.CreateTextFile App.Path & "\" & saveas & "file.txt", True
FCO.OpenTextFile(App.Path & "\" & saveas & "file.txt", ForWriting).Write Text1.Text
End Sub
This reads from a file and puts the results in Text1.Text.
Private Sub save_Click()
Dim sFile as String
sFile = "c:\whatever"
Dim sData as String
Dim fnum as Integer
fnum = FreeFile()
Open sFile For Input As #fnum
If Not eof(fnum) Then
Input #fnum, sData
Text1.Text= sData
End If
Close #fnum
End Sub
You can load in the contents of a file using the standard VB6 file I/O operations
Dim FileNum As Integer
Dim Size As Long
Dim Data() As Byte
'Open the file
FileNum = FreeFile()
Open FileName For Binary As #FileNum
'Read all the data
Size = LOF(FileNum)
ReDim Data(Size - 1)
Get #FileNum, , Data
Close #FileNum
'Convert to a string
TextBox.Text = StrConv(Data, vbUnicode)
See the original article.

Read and write binary file in VBscript

I used earlier ADODB.Stream to read and to write binary file here is the link for that
How to concatenate binary file using ADODB.stream in VBscript
it works fine the only problem is ADODB.stream is disabled on windows 2003 server,
Is there another way i can read 3 files in binary mode and concatenate them or store them in one file in VBscript
thank you
Jp
Based on Luc125 and Alberto answers here are the 2 reworked and simplified functions:
The Read function
Function readBinary(strPath)
Dim oFSO: Set oFSO = CreateObject("Scripting.FileSystemObject")
Dim oFile: Set oFile = oFSO.GetFile(strPath)
If IsNull(oFile) Then MsgBox("File not found: " & strPath) : Exit Function
With oFile.OpenAsTextStream()
readBinary = .Read(oFile.Size)
.Close
End With
End Function
The Write function
Function writeBinary(strBinary, strPath)
Dim oFSO: Set oFSO = CreateObject("Scripting.FileSystemObject")
' below lines pupose: checks that write access is possible!
Dim oTxtStream
On Error Resume Next
Set oTxtStream = oFSO.createTextFile(strPath)
If Err.number <> 0 Then MsgBox(Err.message) : Exit Function
On Error GoTo 0
Set oTxtStream = Nothing
' end check of write access
With oFSO.createTextFile(strPath)
.Write(strBinary)
.Close
End With
End Function
I had a similar problem a year ago. We know that the TextStream objects are intended for ANSI or Unicode text data, not binary data; their .readAll() method produces a corrupted output if the stream is binary. But there is workaround. Reading the characters one by one into an array works fine. This should allow you to read binary data into VB strings, and write it back to disk. When further manipulating such binary strings do not forget that certain operations may result into broken strings because they are intended for text only. I for one always convert binary strings into integer arrays before working with them.Function readBinary(path)
Dim a
Dim fso
Dim file
Dim i
Dim ts
Set fso = CreateObject("Scripting.FileSystemObject")
Set file = fso.getFile(path)
If isNull(file) Then
MsgBox("File not found: " & path)
Exit Function
End If
Set ts = file.OpenAsTextStream()
a = makeArray(file.size)
i = 0
' Do not replace the following block by readBinary = by ts.readAll(), it would result in broken output, because that method is not intended for binary data
While Not ts.atEndOfStream
a(i) = ts.read(1)
i = i + 1
Wend
ts.close
readBinary = Join(a,"")
End Function
Sub writeBinary(bstr, path)
Dim fso
Dim ts
Set fso = CreateObject("Scripting.FileSystemObject")
On Error Resume Next
Set ts = fso.createTextFile(path)
If Err.number <> 0 Then
MsgBox(Err.message)
Exit Sub
End If
On Error GoTo 0
ts.Write(bstr)
ts.Close
End Sub
Function makeArray(n) ' Small utility function
Dim s
s = Space(n)
makeArray = Split(s," ")
End Function
The ADODB stream object is VBScript's only native method of reading binary streams. If ADODB is disabled, you will need to install some other third-party component to provide the same functionality.
It is possible to read all bytes together:
Set FS = CreateObject("Scripting.FileSystemObject")
Set fil = FS.GetFile(filename)
fpga = fil.OpenAsTextStream().Read(file.Size)
ADODB stream object is VBScript's only native method of reading binary streams
Const TypeBinary = 1
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Function readBytes(file)
Dim inStream: Set inStream = WScript.CreateObject("ADODB.Stream") ' ADODB stream object used
inStream.Open ' open with no arguments makes the stream an empty container
inStream.type= TypeBinary
inStream.LoadFromFile(file)
readBytes = inStream.Read()
End Function
Sub writeBytes(file, bytes)
Dim binaryStream: Set binaryStream = CreateObject("ADODB.Stream")
binaryStream.Type = TypeBinary
binaryStream.Open 'Open the stream and write binary data
binaryStream.Write bytes
binaryStream.SaveToFile file, ForWriting 'Save binary data to disk
End Sub
Read 3 files & join to one file (without ADODB):
Dim oFSO : Set oFSO = CreateObject("Scripting.FileSystemObject")
If oFSO.FileExists("out.bin") Then oFSO.DeleteFile("out.bin")
Dim outFile : Set outFile = oFSO.OpenTextFile("out.bin", 8, true)
' 3 input files to concatenate
Dim oFS1 : Set oFS1 = oFSO.GetFile("in1.bin")
Dim oFS2 : Set oFS2 = oFSO.GetFile("in2.bin")
Dim oFS3 : Set oFS3 = oFSO.GetFile("in3.bin")
Dim read1 : Set read1 = oFS1.OpenAsTextStream()
Dim read2 : Set read2 = oFS2.OpenAsTextStream()
Dim read3 : Set read3 = oFS3.OpenAsTextStream()
Dim write1 : write1 = read1.Read(oFS1.Size)
read1.Close
outFile.write(write1)
Dim write2 : write2 = read2.Read(oFS2.Size)
read2.Close
outFile.write(write2)
Dim write3 : write3 = read3.Read(oFS3.Size)
read3.Close
outFile.write(write3)
outFile.Close
Tested on audio, video, image, zip archives & pdf (binaries) on Win 10 for binary file copy, edit, split, join, patching & (byte level) encryption, encoding & compression.
See example (answer) here for binary file patching.

Resources