I'm working with Access 2010's new ribbon feature, and I'm trying to figure out the simplest way to load an image to the ribbon from a table. I know that I could do this by using a GDI API function, but from what I can see the code looks convoluted and appears to utilize extra dlls that I would just as well avoid calling if I don't need to. I also know that I could create a control on a form, load the image to the form, and then load the image from the form to the ribbon image variable. While using the form is doable, it seems sloppy. Eventually, I will resort to one of the two preceding methods if I have to, but it just seems like there should be some simple way to load an image from a table directly into an image variable for the ribbon.
One thing to note is that I'm willing to use whatever image format is easiest. These icon files are very small and so I'm not concerned about file size and I also don't care whether or not they are capable of transparency. So if there's a method that only works with bitmap file types that is fine with me.
Here's the code I have for the button in the ribbon XML:
<button id="CCTrans" label="Credit Card Trans." getImage="GetMnuIcn" onAction="=OpenCCTrans()" />
And here's the code I have for retrieving the image:
Sub GetMnuIcn(control As IRibbonControl, ByRef Image)
Set Image = DLookup("Img", "LtblImg", "Lbl=""" & control.ID & """")
End Sub
I've tried storing the image both as an OLE Object and as an attachment. Either way, when I try to retrieve it, it gives me the error "Type Mismatch". For simplicity, I've been storing it as a bitmap, but I also tried .gif and .png in my first attempts.
Note: Apparently the ribbon icons are IPictureDisp objects. If I can just figure out how to load an image from a table into one of those object types, I should be able to use it for the ribbon.
Also, there's a lot of good information on Microsoft's website, but I haven't been able to piece it together into a solution yet. Here's a link: http://msdn.microsoft.com/en-us/library/bb187398.aspx
Well after tedious days of trying to find a better solution, I'm forced to pick between what I feel are various mediocre approaches. I really wanted to just load it directly into a variable, but the only method for doing that requires references to a bunch of dlls and has code that is pretty complicated. To avoid any extra dependencies and to keep my code simpler, I decided to go the route of assigning the table containing the attached images to a form, opening that form in hidden mode and then assigning the picture variables from the form.
For some reason the code that I saw elsewhere that loaded the pictures on demand via this method caused my program to crash and so I had to load the pictures into variables when the program opened and then have the menu bar set the icons from those variables when the menu is selected.
My code is as follows:
Dim Icn(15) As IPictureDisp, IcnLbl(15) As String
Function SetMnuIcn()
Dim Img As Recordset, i As Byte
DoCmd.OpenForm "frmImg", acNormal, , , acFormReadOnly, acHidden
Set Img = Forms!frmImg.Recordset
While Not Img.EOF
i = i + 1
Set Icn(i) = Forms!frmImg!Img.PictureDisp
IcnLbl(i) = Img!Lbl
Img.MoveNext
Wend
DoCmd.Close acForm, "frmImg", acSaveNo
End Function
Sub GetMnuIcn(control As IRibbonControl, ByRef Image)
Set Image = Icn(GetAryLoc(IcnLbl, control.ID, 15))
End Sub
Function GetAryLoc(varValues As Variant, varMatch As Variant, NumOfValues As Integer) As Integer
Dim i As Integer
For i = 1 To NumOfValues
If varValues(i) = varMatch Then GetAryLoc = i
Next
End Function
Note: To ensure that the icons have been loaded prior to when they are needed, I specified SetMnuIcn to run on ribbon load:
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="=SetMnuIcn()">
Related
I have a macro that takes a range of cells, copies them as an image, and places them in a separate sheet. I would like to take the image, resize it, and place the correctly sized image into a different sheet.
Sub heatmapToJPEG()
Range("G1:V33").Select
Selection.CopyPicture Appearance:=xlScreen, Format:=xlPicture
'places image of heat map into Setup tab
Sheets("Setup").Select
Range("M1").Select
ActiveSheet.Paste
End Sub
I would like to re-size the image one it is in the Setup tab, but when excel places it there, it gives it the default name of Picture 1, Picture 2, Picture 3, or whatever iteration I am on before closing and reopening the workbook.
Is there a way to assign a permanent variable name to the image found in the Setup tab? If so, my thinking was to assign it to the variable name, and pass it off to another sub for resizing and placement. I am sure there are better ways, but am hitting this roadblock.
It's bad practice all around but just add a .Name property at the end -
ActiveSheet.Paste
Selection.Name = "name"
I have looked far and wide and reached the end of my wits trying to figure out how to do this. I have looked on XtremeVBTalk.com and the rest of the internet on how to resize a damn StdPicture!
Does anyone know how to do this? Is this even possible?
Thank you so much in advance. I desire not to use any type libraries etc. so if that is offered in a solution I don't think I will be able to use it.
I'm not using A picturebox control at all.
Say I have the following function header, and an StdPicture is passed in:
Private Function EncodeImageToBase64(ByRef Image As StdPicture) As String
I then have the following declarations where I intend on encoding the StdPicture to base64:
Dim xmlDoc As DOMDocument60
Dim xmlNode As MSXML2.IXMLDOMElement
Dim bColor() As Byte
Dim bMask() As Byte
Dim bImage() As Byte
Dim lCrcTable() As Long
Dim lWidth As Long
Dim lHeight As Long
EncodeImageToBase64 = vbNullString
If Image Is Nothing Then
Exit Function
End If
Call CRCTable(lCrcTable)
Call Icon2Arrays(Image, bColor, bMask, lWidth, lHeight)
If Not CreatePngByteArray(bImage, lWidth, lHeight, bColor, bMask, lCrcTable) Then
Debug.Assert False
Exit Function
End If
However, before calling that, I want to cut the image's width and height in half. How can I do so? CreatePngByteArray only supports 16x16 PNGs and I am using 32x32, so I'd like to cut them down in order to pass the asserts they have.
OK, I spent quite some time that I didn't really have on this one, because I didn't know the answer to begin with, but I was still interested in finding out what the potential solution was.
The following answer is my understanding of what you are trying to do, but may not be the answer to the question itself, so it could very well be considered wrong.
So, here's what I came up with. You will need to use an IPictureDisp object instead of an StdPicture object. You will also need to use a PictureBox control, even if you don't really want to.
Create a new project. Add a form, or open an existing one if one is provided. Set the ScaleMode of the form to pixels. Add a PictureBox control on the form. Set the AutoRedraw property of the PictureBox control to 'True', the BorderStyle property of the control to 'None', and the Height and Width properties of the control to 16 pixels each. Add the following code to the form, and modify the location and type of the image that you want to resize, and then the location to save it to:
Private Sub Form_Load()
Dim TestPic As IPictureDisp
Set TestPic = LoadPicture("C:\Users\Your Name\Desktop\image.gif")
With TestPic
.Render Picture1.hDC, 0, 16, 16, -17, 0, 0, .width, .height, 0
End With
SavePicture Picture1.Image, "C:\Users\Your Name\Desktop\image2.bmp"
End Sub
The image can start with any of the types that Visual Basic 6 supports (.bmp, .cur, .gif, .ico, .jpeg or .jpg, and .wmf), but must always be saved in bitmap format. Please note that Visual Basic 6 does not support PNG file formats at all, so you will not be able to use any VB6 functions to open PNG files or create them.
I would be interested in other solutions that other people come up with.
Edit: Fixed dimensions.
Do you mean inside the PICTUREBOX control or inside an IMAGE CONTROL? Because If I remember correctly it has a STRETCH property which autofits the image to the container
#Zaf Khan beat me to it. I have something similar where I have a PictureBox. Under behaviour I have SizeMode set to StretchImage then when I load an image like so
LoadWebImageToPictureBox(ImagePreview, SelectedFile)
it auto fits.
I'm working on a macro for a friend of mine who needs to import a set of images in an excel document and later use this document on other computers. The problem I encountered is that when opening this document on a different computer, all the images are gone and instead you get these little error signs, indicating that the image path could not be found.
I have developed the macro on my own computer where I have Excel 2007 and for me, the code works perfectly fine. My friend uses Excel 2013 and apparently, there seems to be a major difference on how those 2 versions deal with the image importing and saving.
Overall, I found 2 different ways how to insert images. The first one I tried was something similar to this:
Set pic = ActiveSheet.Pictures.Insert("C:\documents\somepicture.jpg")
The second way of doing this looked like this:
Set pic = Application.ActiveSheet.Shapes.AddPicture("C:\documents\somepicture.jpg", False, True, 1, 1, 1, 1)
In the documentation for this 2nd approach it is said that the 3rd paramenter (which is True here) is responsible for saving the picture with the document.
However, both these approaches look more or less the same in the end result: They work fine for me but won't work if they are executed on my friends pc with Excel 2013. So what I need is a work-around for the newer Excel versions (I read somewhere that from Excel 2010 upwards, there is a bug or something like that with these image import methods).
In all my uses, Adding a picture with Insert makes a reference to a file on your harddrive, for whatever reason if you want the image to be embedded in the file you have to add a shape and then put the image on the shape using the AddPicture (like you use), I have never had any issues with this.
Also you are giving the picture a height and width of 1 pixel, You will almost never be able to see that true setting that higher as below:
Application.ActiveSheet.Shapes.AddPicture "C:\documents\somepicture.jpg", False, True, 1, 1, 100, 100
I have a feeling it was working all along and you just never saw the picture cause it was too small.
The first snippet works just fine, but it does not allow picture positioning (i.e. if you need a pic placed at some certain range), so I made something that works nicely with positioning available, based on the second solution, such as it is shown below.
Dim r As Range
Dim pic As Shape
Set r = ActiveSheet.Range("A34:Q58")
Set pic = ActiveSheet.Shapes.AddPicture(ThisWorkbook.Path & "\FracAnalysis.png", _
linktofile:=msoFalse, savewithdocument:=msoCTrue, Left:=0, Top:=0, Width:=-1, Height:=-1)
With pic
.LockAspectRatio = msoFalse
.Top = r.Top
.Left = r.Left
.Width = r.Width
.Height = r.Height
End with
Previous answer has been really useful! I just wanted to add the reference to the method parameters (I thought the width and height were in pixels, turns out they're in points):
https://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.shapes.addpicture.ASPX
I usually run a macro that downloads images from a server into files that are then forwarded to clients who do not have access to that server. My coding is quite basic so I'll just copy the particular line I use to insert the picture:
Set pic = ActiveSheet.Shapes.AddPicture(Filename:="C:\documents\somepicture.jpg", _
linktofile:=msoFalse, savewithdocument:=msoCTrue, Left:=0, Top:=0, Width:=-1, Height:=-1)
I know its technically the same code as the one you proposed, but try using msoCTrue and msoFalse. I seem to recall that being part of the issues. Let me know if it works and maybe we can try something else. It works for me, so we should be able to get it to work for you.
I have some images and videos in my powerpoint presentation. Depends of what format have each one (jpg, mp3, jpeg,...) I want it to make a different thing so I need to know what kind of file is it. Is there anything in Visual Basic to make it?
EDITED
I want to difference the images and videos supported by iPad with the ones that are not supported. That is why I need to know the format of them.
EDIT: to state it clear- solution below works only with shapes which are linked to files!
Function WhatTypeOfMedia(SHP As Shape)
Select Case Right(SHP.LinkFormat.SourceFullName, 4)
Case ".jpg", "jpeg"
WhatTypeOfMedia = "Picture type"
Case ".wav", ".mp3"
WhatTypeOfMedia = "Music type"
'... end other possible types put here
End Select
End Function
To make a test run for 1st slide of active presentation try this code:
Sub Take_format_Linked()
On Error Resume Next 'required for these files which are not linked
Dim SHP As Shape
For Each SHP In ActivePresentation.Slides(1).Shapes
'1st check if format is linked- best option:
If Len(SHP.LinkFormat.SourceFullName) > 0 Then
If Err.Number = 0 Then
'if so, let's call function
Debug.Print WhatTypeOfMedia(SHP)
'here you can do what you want based on function result
Else
Err.Clear
End If
End If
Next
End Sub
As a result you get information in Immediate window which shape is which type. You could use that types to run what you need in main sub.
In that simple idea I kept On Error Resume Next to avoid error if Shape is not linked.
As has been pointed out, you can get the file types for linked files, but there's no way to get them for embedded files. However, if you don't need to do it in VBA or can manipulate ZIP files in VBA, open the PPTX as a zip and look for the media folder. There you'll find any embedded files (pictures, sounds, movies).
They may not be in the same format as they originally were in; PPT sometimes converts images when it imports them. But that shouldn't be an issue considering what you're after.
I'm using the Crystal Reports included with VisualStudio 2005. I would like to change the image that is displayed on the report at runtime ideally by building a path to the image file and then have that image displayed on the report.
Has anyone been able to accomplish this with this version of Crystal Reports?
At work we do this by pushing the image(s) into the report as fields of a datatable. It's not pretty, but it gets the job done. Of course, this solution requires that you push data into the reports via a DataSet. I've always felt this was a hack at best. I really wish that image parameters were a possibility with CR.
Edit: It's worth noting, if you are binding your crystal report to plain old objects you want to expose a byte[] property for the report to treat that as an image.
I finally reached a solution using the byte[] tip posted here by Josh.
This solution applies if you are using a plain old C# Object to populate your Crystal Reports (see http://www.aspfree.com/c/a/C-Sharp/Crystal-Reports-for-Visual-Studio-2005-in-CSharp/ for info on this approach).
In your C# class, insert the following code:
private static byte[] m_Bitmap = null;
public byte[] Bitmap
{
get
{
FileStream fs = new FileStream(bitmapPath, FileMode.Open);
BinaryReader br = new BinaryReader(fs);
int length = (int)br.BaseStream.Length;
m_Bitmap = new byte[length];
m_Bitmap = br.ReadBytes(length);
br.Close();
fs.Close();
return m_Bitmap;
}
}
Now, update your C# Object Mapping in CR using the "Verify Database" option. You should then see the Bitmap property as a CR field. Just drag it onto the form. It will be of type IBlobFieldObject. When you run, you should see your image.
[I have since found a solution using a byte array via a C# Object property - see separate Answer. Leaving this answer here for reference...]
Here's what I have seen suggested (but I tried and failed in both C#-2005 and C#-2008).
Choose a directory and place a BMP there (e.g., "C:\Temp\image.bmp").
From the CR-Designer a) Right-click->Insert->OLE Object... b) Select "Create from File" c) Check the "Link" checkbox d) Browse and pick the bmp defined in step 1 e) Click OK f) Place the image on the form.
Overwrite/update the image at runtime in your C# code. In theory, since you inserted a Link to an image file, it will be updated when the form is refreshed.
I had no luck with this approach. The image appears when I first design the form (step 2). But at runtime, the image does not update for me. From this point forward, things get really odd. It seems that CR caches some sort of image that just won't go away. I can delete the OLE object link in CR-Designer, but if I recreate it, I always get a black box the same size as the original image (even if I change the size of image.bmp).
You can also use a conditional formula to set an image's location. See Crystal Reports: Dynamic Images.
Try using a combination of using a parameter containing the path of the image and the tutorial on this page: http://www.idautomation.com/crystal/streaming_crystal.html
Then in step #8, use the parameter instead of a hard-coded path.
Another option that I've found useful is inserting the pictures you would like to use. Position the graphic accordingly, then right-click the graphic and go to Format Graphic > Common. Check the Suppress box, then click the formula button, shown as x-2. Once in the formula window, simply add the code for determining whether the graphic should be suppressed or not.
In my case, I was building one invoice template for multiple entities. In the formula window, I simply wrote COMPANY <> 1100 which meant that every time the invoice was run for a company other than 1100, the 1100 graphic would be suppressed.
Hopefully this makes life easier...
The current version of Crystal Reports (for Visual Studio 2012+) that I use with Visual Studio 2015 supports this function. Follow the following steps:
Insert a picture into your report. This will serve as your
placeholder.'
Right click your picture and choose Format Object
Select the Picture tab and the press the formula button
A formula window will open. Enter a formula that will find your pictures as links.
if({#isDonor}="1")
then "http://www.ny.org/images/aaf/picture1.jpg"
else "http://www.ny.org/images/aaf/picture2.jpg"
And you're done!
Just like Josh said.. You will have to push the image with a dataset. Or, put the image into a database table once and pull it in many times with a subreport.