Linking v Embedded

J

Jim Bunton

adding one LINKED image (jpg) of c713Kb to an access database of c 14,000 kb
immediately increases its size to c 33,000Kb - and it goes on increasing in
size in similar jumps with the linking or more images.

BUT adding LINKED images to a word doc hardly increases their size at all -
which is what I'd expect

I'm pretty sure I'm NOT Embedding the image
OLE Type Allowed Linked
Display Type Content
update option Automatic

The image doesn't inherit changes made to the original either - which is
what I woulod expect with a linked object

The object is inserted using code:

Me.paPhoto.SourceDoc = ReturnedFilePath
Me.paPhoto.Action = acOLECreateLink
Me.paPhoto.SizeMode = 3

?? What's going on please ??

--
Jim Bunton
(e-mail address removed)
13 Westbourne Road
Trowbridge
Wilts. BA14 0AJ
Tel: 01225 765 541
Mobile: 07919 283 968
 
L

Lynn Trapp

With Access OLE objects tend to cause a database to bloat, regardless of
whether they are linked or embedded. The best approach is to only store the
path to your image and, then, display it on a form or report only as needed.
The Employee form in the Northwind database has a good example of how to do
this.

--
Lynn Trapp
MS Access MVP
www.ltcomputerdesigns.com
Access Security: www.ltcomputerdesigns.com/Security.htm
Jeff Conrad's Access Junkie List:
http://home.bendbroadband.com/conradsystems/accessjunkie.html
 
J

Jim Bunton

Thanks for the reply Lynn
Sounds like a great idea but in the latest Northwing I have ( on Office 2000
CD) the image is stored as a Bit map OLE object. Can't see the idea you've
mentioned.
 
C

Chris Mills

Here's an old post I happen to have kept on the subject.
Chris


----- Original Message -----
From: "Frank Miller" <[email protected]>
Newsgroups: microsoft.public.access.developers.toolkitode
Sent: Tuesday, November 13, 2001 11:04 AM
Subject: RE: Catalog Application - Picture Handling


Hi Beau,

My name is Frank Miller. Thank you for using the Microsoft Access
Newsgroups.

There are primary two ways to get images onto an Access 97 form or report,
either we embed the images in the database or we create links in the
database to the image files.

The embed method is easier to distribute but creates a much larger database
file.

The link method saves considerable space in the database but requires that
the path is valid at the time the image is displayed.

Thumbnail images can also be utilized by including a second, smaller
version of each image, or by simply scaling down the image display in the
form or report.

In the following example, a form is used to load and display images, a
report is used that will print both the embedded and linked images, and a
database table is created that contains both embedded and a linked JPG
images. Although JPG images were used in this example, other image types
can also be used.

On a Windows 98 platform, the database table uses a Text field to store the
image link and an OLE Object field to store the embedded image.

First we create a database that contains, as a minimum, a text field which
is the source for the image link and a OLE Object field which is where the
embedded image is stored.

Next, we create a Form that will both link, embed, and display both types
of the selected image file. On the form we need a Common Dialog ActiveX
control (named ActiveXCtl3 in the example below) to get the image path, a
Command Button (named Load New Image) to get new images, a Text box (named
Text2) to display the image file path, an Image box (named Image4) to
display the linked image, and a Bound Object Frame (named OLEBound10), that
is bound to the embedded image in the database.
Sample code:

The routine below is good for loading OLE objects, such as .gif, .jpg,
doc, .xls, or .bmp files that are associated with an OLE Server, into a
Microsoft Access database. We can set the Image control's Picture Property
to any .bmp, .ico, .wmf, .dib, or .emf file on your hard disk. If you have
installed graphics filters for other programs, you can use any file
supported by those filters (such as TIF files).

NOTE: To associate a graphic file with an OLE Server, open it with an OLE
Server package, such as Microsoft Imager or Microsoft Paint, and save the
file.

If you receive an error opening the image, please see article:

Q294255 - ACC2000: Err Msg When You Attempt to Display Images on a Form

http://support.microsoft.com/support/kb/articles/q294/2/55.asp

The following subroutine loads the linked image to the form when the form
opens and when the user selects a new record in the database. The On Error
Resume Next is used to avoid an error message when there is no link or when
the link does not point to a valid image file.

Private Sub Form_Current()
On Error Resume Next
Me.Image4.Picture = Me.Text2
End Sub

This subrountine runs when the Load New Image button is clicked. It
displays the Open File dialog box so that the user can select a new image
file, links the file, displays the image, and embeds the image in to the
database.

Private Sub Command1_Click()
Me.ActiveXCtl3.ShowOpen
'Linked Image Code
Me.Text2 = ActiveXCtl3.FileName
Me.Image4.Picture = Me.Text2
'Embedded Image Code
Me.OLEBound.OLETypeAllowed = acOLEEmbedded
Me.OLEBound.SourceDoc = ActiveXCtl3.FileName
Me.OLEBound.Action = acOLECreateEmbed
Me.Refresh
End Sub

We can now create a report to display the embedded image is in a bound
object frame and the linked images with the following code:

Private Sub Detail_Print(Cancel As Integer, PrintCount As Integer)
On Error Resume Next
Me.Image9.Picture = Me.MyImage
End Sub

This example could be further modified to display only the desired file
types in the Open File dialog. For additional information, please see the
CommonDialog Control's Filter Property in the help file. If the application
is to be distributed to other machines I would favor using VBA code, rather
than the Commod Dialog Control to select the images. See article Q161286 -
HOWTO: Use a Common Dialog File Open Dialog with Win32 API

Image Quality:
When we both Link and Embed the same file at the same time, we should not
see any difference in the image quality.

When we Embed the image in an OLE Object, we "wrap" the image with the OLE
Server information so it will display even after we have removed the OLE
Server (such as Photo Editor) from the computer.

When we Link the image file we use whatever OLE Server is installed to
display the image, or, if there is no OLE Server installed, then we use the
Graphics Filters that are installed with Office.

For example, if we try to Link to a TIF file and there are no OLE Server
applications installed that would display a TIF file, the TIF file won't
display linked in Access because Office does not install the TIF graphics
filter by default.

If we did the same thing using a BMP file, it would display because we
install the BMP, JPG and several other graphics filters by default.

In Office Setup, Add/Remove Features, Converters and Filters, Graphic
Filters, you can see and change which graphics filters are installed.

To see which OLE Server is currently being used by the operating system for
a file type, double click on an image file with the same extension as the
one you are linking to (EG: BMP, JPG), and see what application it opens in.

When we double-click a JPG file, it will often display in Internet
Explorer(IE). IE is not an OLE Server so it is the default JPG graphics
filter that is enabling the JPG file to be displayed as linked in Access.
By the same token, we can't embed a JPG file even though it can be
displayed in both Access as a linked file and in IE.

To embed a and display a JPG file, we would still need an OLE Server. Even
is an OLE Server that supported JPG files was subsequently installed, the
"wrapper" in the Access OLE Object field would be incorrect until we
removed the image from the database and reinstalled the image with a valid
OLE Server available.

For additional information please see article Q158941: How to Load OLE
Objects from a Folder into a Table, available from the internet at:

http://support.microsoft.com/support/kb/articles/q158/9/41.asp

For Access 2000, see the following articles:

Q198466 ACC2000: How to Load OLE Objects from a Folder into a Table at:

http://support.microsoft.com/support/kb/articles/q198/4/66.asp

Q114214: How to Programmatically Embed or Link an Object in a Form,
available from the internet at:

http://support.microsoft.com/support/kb/articles/q114/2/14.asp

Q210100 - ACC2000: How to Display an Image from a Folder in a Form

http://support.microsoft.com/support/kb/articles/q210/1/00.asp

Because Word install most of the Office Graphics Filters, the following
articles may also be of Interest:

Q210396 - OFF2000: Descriptions, Limitations of Shipped Graphics Filters

http://support.microsoft.com/support/kb/articles/q210/3/96.asp

Q212271 - WD2000: Graphics Filters Installed in an "Install Now" Setup

http://support.microsoft.com/support/kb/articles/q212/2/71.asp

Q212265 - WD: Additional Converters/Filters Available in Converter Pack

http://support.microsoft.com/support/kb/articles/q212/2/65.asp

Q235928 - WD2000: Supported File and Graphics Formats

http://support.microsoft.com/support/kb/articles/q235/9/28.asp

I hope this helps! If you have additional questions on this topic, please
reply to this posting.

Regards, Frank Miller
Microsoft Support

This posting is provided “AS IS” with no warranties, and confers no rights.
 
J

Jim Bunton

Thanks for the reply Chris

There's quite a lot to go on there - will read it with interest

In the mean time:-
What I've done is this:-
Put an image on the form
[called PathOfPhoto]
picture property:
an image which will display at form open
PictueType property: Linked
Size Mode property: Zoom
Picture alignment property: Center

create a browse button which runs the code below

---------- Code ------------
Private Sub BrowseCmd_Click()
On Error GoTo Err_BrowseCmd_Click
Dim strFilter As String
Dim lngFlags As Long
Dim srchDir As String
Dim ReturnedFilePath As String

ReturnedFilePath = ahtCommonFileOpenSave(InitialDir:=srchDir, _
Filter:=strFilter, FilterIndex:=0, Flags:=lngFlags, _
DialogTitle:="Select File", hwnd:=Me.hwnd)
Me.PathOfPhoto.Picture = ReturnedFilePath
Exit_BrowseCmd_Click:
Exit Sub

Err_BrowseCmd_Click:
Dim ErrMsg
If Err = 2702 Then
ErrMsg = "The file selected is not of an appropriate type"
Else
ErrMsg = Err & " - " & Err.Description
End If
MsgBox ErrMsg, 0, "Select File Error"
Resume Exit_BrowseCmd_Click

End Sub
--------- Code End --------------

It will be pretty straight forward to enter ReturnedFilePath into a field in
the database table
and also read the current one

Big upside - NO DATABASE BLOATING
Downside - the image takes a short time to load BUT if it's small [and wht
shouldn't it be!] then it loads very quickly.
+ you must take care to leave the images where they are in the filing
system
[Maybe this is what Lynn Trap was suggesting (see a first response to
original post)

Jim

PS
[goes down quite a way to ########### End of PS ##########]
here's the code to define and run ahtCommonFileOpenSave
It looks pretty horrendous and needs a bit of tidying up
but it's not half as daunting as it looks
the code below can just be put in a new module
[and tidied up!!]
*********** Begin Module *************

Option Compare Database
Option Explicit

------------- Code Start --------------------
'This code was originally written by Ken Getz.
'It is not to be altered or distributed,
'except as part of an application.
'You are free to use it in any application,
'provided the copyright notice is left unchanged.
'
' Code courtesy of:
' Microsoft Access 95 How-To
' Ken Getz and Paul Litwin
' Waite Group Press, 1996

Type tagOPENFILENAME
lStructSize As Long
hwndOwner As Long
hInstance As Long
strFilter As String
strCustomFilter As String
nMaxCustFilter As Long
nFilterIndex As Long
strFile As String
nMaxFile As Long
strFileTitle As String
nMaxFileTitle As Long
strInitialDir As String
strTitle As String
Flags As Long
nFileOffset As Integer
nFileExtension As Integer
strDefExt As String
lCustData As Long
lpfnHook As Long
lpTemplateName As String
End Type

Declare Function aht_apiGetOpenFileName Lib "comdlg32.dll" _
Alias "GetOpenFileNameA" (OFN As tagOPENFILENAME) As Boolean

Declare Function aht_apiGetSaveFileName Lib "comdlg32.dll" _
Alias "GetSaveFileNameA" (OFN As tagOPENFILENAME) As Boolean

Declare Function CommDlgExtendedError Lib "comdlg32.dll" () As Long

Global Const ahtOFN_READONLY = &H1
Global Const ahtOFN_OVERWRITEPROMPT = &H2
Global Const ahtOFN_HIDEREADONLY = &H4
Global Const ahtOFN_NOCHANGEDIR = &H8
Global Const ahtOFN_SHOWHELP = &H10
' You won't use these.
'Global Const ahtOFN_ENABLEHOOK = &H20
'Global Const ahtOFN_ENABLETEMPLATE = &H40
'Global Const ahtOFN_ENABLETEMPLATEHANDLE = &H80
Global Const ahtOFN_NOVALIDATE = &H100
Global Const ahtOFN_ALLOWMULTISELECT = &H200
Global Const ahtOFN_EXTENSIONDIFFERENT = &H400
Global Const ahtOFN_PATHMUSTEXIST = &H800
Global Const ahtOFN_FILEMUSTEXIST = &H1000
Global Const ahtOFN_CREATEPROMPT = &H2000
Global Const ahtOFN_SHAREAWARE = &H4000
Global Const ahtOFN_NOREADONLYRETURN = &H8000
Global Const ahtOFN_NOTESTFILECREATE = &H10000
Global Const ahtOFN_NONETWORKBUTTON = &H20000
Global Const ahtOFN_NOLONGNAMES = &H40000
' New for Windows 95
Global Const ahtOFN_EXPLORER = &H80000
Global Const ahtOFN_NODEREFERENCELINKS = &H100000
Global Const ahtOFN_LONGNAMES = &H200000


Function TestIt()
Dim strFilter As String
Dim lngFlags As Long
strFilter = ahtAddFilterItem(strFilter, "Access Files (*.mda, *.mdb)", _
"*.MDA;*.MDB")
strFilter = ahtAddFilterItem(strFilter, "dBASE Files (*.dbf)", "*.DBF")
strFilter = ahtAddFilterItem(strFilter, "Text Files (*.txt)", "*.TXT")
strFilter = ahtAddFilterItem(strFilter, "All Files (*.*)", "*.*")
MsgBox "You selected: " & ahtCommonFileOpenSave(InitialDir:="C:\", _
Filter:=strFilter, FilterIndex:=3, Flags:=lngFlags, _
DialogTitle:="Hello! Open Me!")
' Since you passed in a variable for lngFlags,
' the function places the output flags value in the variable.
'Debug.Print Hex(lngFlags)
End Function


Function GetOpenFile(Optional varDirectory As Variant, _
Optional varTitleForDialog As Variant) As Variant
' Here's an example that gets an Access database name.
Dim strFilter As String
Dim lngFlags As Long
Dim varFileName As Variant
' Specify that the chosen file must already exist,
' don't change directories when you're done
' Also, don't bother displaying
' the read-only box. It'll only confuse people.
lngFlags = ahtOFN_FILEMUSTEXIST Or _
ahtOFN_HIDEREADONLY Or ahtOFN_NOCHANGEDIR
If IsMissing(varDirectory) Then
varDirectory = ""
End If
If IsMissing(varTitleForDialog) Then
varTitleForDialog = ""
End If

' Define the filter string and allocate space in the "c"
' string Duplicate this line with changes as necessary for
' more file templates.
strFilter = ahtAddFilterItem(strFilter, _
"Access (*.mdb)", "*.MDB;*.MDA")
' Now actually call to get the file name.
varFileName = ahtCommonFileOpenSave( _
OpenFile:=True, _
InitialDir:=varDirectory, _
Filter:=strFilter, _
Flags:=lngFlags, _
DialogTitle:=varTitleForDialog)

If Not IsNull(varFileName) Then
varFileName = TrimNull(varFileName)
End If
GetOpenFile = varFileName
End Function


Function ahtCommonFileOpenSave( _
Optional ByRef Flags As Variant, _
Optional ByVal InitialDir As Variant, _
Optional ByVal Filter As Variant, _
Optional ByVal FilterIndex As Variant, _
Optional ByVal DefaultExt As Variant, _
Optional ByVal FileName As Variant, _
Optional ByVal DialogTitle As Variant, _
Optional ByVal hwnd As Variant, _
Optional ByVal OpenFile As Variant) As Variant

' This is the entry point you'll use to call the common
' file open/save dialog. The parameters are listed
' below, and all are optional.
'
' In:
' Flags: one or more of the ahtOFN_* constants, OR'd together.
' InitialDir: the directory in which to first look
' Filter: a set of file filters, set up by calling
' AddFilterItem. See examples.
' FilterIndex: 1-based integer indicating which filter
' set to use, by default (1 if unspecified)
' DefaultExt: Extension to use if the user doesn't enter one.
' Only useful on file saves.
' FileName: Default value for the file name text box.
' DialogTitle: Title for the dialog.
' hWnd: parent window handle
' OpenFile: Boolean(True=Open File/False=Save As)
' Out:
' Return Value: Either Null or the selected filename
Dim OFN As tagOPENFILENAME
Dim strFileName As String
Dim strFileTitle As String
Dim fResult As Boolean
' Give the dialog a caption title.
If IsMissing(InitialDir) Then InitialDir = CurDir
If IsMissing(Filter) Then Filter = ""
If IsMissing(FilterIndex) Then FilterIndex = 1
If IsMissing(Flags) Then Flags = 0&
If IsMissing(DefaultExt) Then DefaultExt = ""
If IsMissing(FileName) Then FileName = ""
If IsMissing(DialogTitle) Then DialogTitle = ""
If IsMissing(hwnd) Then hwnd = Application.hWndAccessApp
If IsMissing(OpenFile) Then OpenFile = True
' Allocate string space for the returned strings.
strFileName = Left(FileName & String(256, 0), 256)
strFileTitle = String(256, 0)
' Set up the data structure before you call the function
With OFN
.lStructSize = Len(OFN)
.hwndOwner = hwnd
.strFilter = Filter
.nFilterIndex = FilterIndex
.strFile = strFileName
.nMaxFile = Len(strFileName)
.strFileTitle = strFileTitle
.nMaxFileTitle = Len(strFileTitle)
.strTitle = DialogTitle
.Flags = Flags
.strDefExt = DefaultExt
.strInitialDir = InitialDir
' Didn't think most people would want to deal with
' these options.
.hInstance = 0
.strCustomFilter = ""
.nMaxCustFilter = 0
.lpfnHook = 0
'New for NT 4.0
.strCustomFilter = String(255, 0)
.nMaxCustFilter = 255
End With


' This will pass the desired data structure to the
' Windows API, which will in turn it uses to display
' the Open/Save As Dialog.
If OpenFile Then
fResult = aht_apiGetOpenFileName(OFN)
Else
fResult = aht_apiGetSaveFileName(OFN)
End If

' The function call filled in the strFileTitle member
' of the structure. You'll have to write special code
' to retrieve that if you're interested.
If fResult Then
' You might care to check the Flags member of the
' structure to get information about the chosen file.
' In this example, if you bothered to pass in a
' value for Flags, we'll fill it in with the outgoing
' Flags value.
If Not IsMissing(Flags) Then Flags = OFN.Flags
ahtCommonFileOpenSave = TrimNull(OFN.strFile)
Else
ahtCommonFileOpenSave = "NoFile"
End If
End Function


Function ahtAddFilterItem(strFilter As String, _
strDescription As String, Optional varItem As Variant) As String
' Tack a new chunk onto the file filter.
' That is, take the old value, stick onto it the description,
' (like "Databases"), a null character, the skeleton
' (like "*.mdb;*.mda") and a final null character.

If IsMissing(varItem) Then varItem = "*.*"
ahtAddFilterItem = strFilter & _
strDescription & vbNullChar & _
varItem & vbNullChar
End Function


Private Function TrimNull(ByVal strItem As String) As String
Dim intPos As Integer
intPos = InStr(strItem, vbNullChar)
If intPos > 0 Then
TrimNull = Left(strItem, intPos - 1)
Else
TrimNull = strItem
End If
End Function
-----------------Code End -----------------------


'To call the actual dialog from your code, see the enclosed function
TestIt() within the module
'or use the following example as a guideline and

'Dim strFilter As String
'Dim strInputFileName As String
'
'strFilter = ahtAddFilterItem(strFilter, "Excel Files (*.XLS)", "*.XLS")
'strInputFileName = ahtCommonFileOpenSave(Filter:=strFilter, OpenFile:=True,
_
' DialogTitle:="Please select an input file...", _
' Flags:=ahtOFN_HIDEREADONLY)
'
''Note that in order to call the Save As dialog box, you can use the same
wrapper function by just setting the
''OpenFile option as False. For example,
'
'
''Ask for SaveFileName
'strFilter = ahtAddFilterItem(myStrFilter, "Excel Files (*.xls)", "*.xls")
'strSaveFileName = ahtCommonFileOpenSave(OpenFile:=False, Filter:=strFilter,
_
' Flags:=ahtOFN_OVERWRITEPROMPT Or ahtOFN_READONLY)


########### End of PS ##########
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

OLE server error 2753 0
My Macro 1
View Source doesn't work 0
Access 2000 Locked/Readonly 0
Append usrNew 3
Reading/Saving Attachments 1
Append New user to A Group 5
Outlook connector crashes outlook 0

Top