Excel: create image from cell range - image

Using Excel VBA, I want to create an image showing the content of a cell.
Manually, I can do this by selecting a cell, clicking on 'copy', selecting another cell, and clicking on 'paste as image'. Then I can select the image and set its formula to =$B$2, for example.
The Macro recorder tells me that this is equivalent to the following code:
Selection.Copy
ActiveSheet.Pictures.Paste.Select
ActiveCell.FormulaR1C1 = "=R[1]C[1]"
I want to achieve the same without using the copy-paste-select commands. In other words, I would like to create a Picture object with predefined FormulaR1C1 property.
I tried ActiveSheet.Pictures.Add(Left, Top, Width, Height) but only got Runtime error '1004': No link to paste. I don't understand what this means.
I tried ActiveSheet.Pictures.Insert and ActiveSheet.Shapes.AddPicture, but they both require a file name to load an external image file, which is not what I want.

Instead of copying the cell, then telling it you want to paste to another cell as a picture, try using:
Range("A1").CopyPicture Appearance:=xlScreen, Format:=xlPicture
Now A1 is in your clipboard as a picture. You can use boring old paste to stick it somewhere else.
Range("B1").Select
ActiveSheet.Paste

Are you trying to get a "live" picture which is linked back to the source range, like using the Camera tool in Excel?
Sub Macro1()
Dim s, rng As Range, rngDest As Range
Set rng = ActiveSheet.Range("B2:C3")
Set rngDest = ActiveSheet.Range("E10")
rng.Copy
With ActiveSheet.Pictures.Paste(link:=True)
.Left = rngDest.Left
.Top = rngDest.Top
End With
End Sub
I don't think you can get around using copy/paste though.

Related

Powerpoint: How to repeat a picture without placing it in the masterslides?

I want to make a template for my colleagues. They should be able to place the customer logo on the first slide and then have the logo on all slides. I don't want them to open the masterslides and place the logo there, because this will cause human errors.
My idea would be to put a placeholder for pictures on all slides and link the contents, so that when a picture is placed in one of them, that the others show the same picture. But I can't find an option for that.
Anyone got an idea how to do that?
PowerPoint doesn't do this "out of the box". You'd need to provide a programmed solution (eg. in the form of an add-in) that would do the job for them, either by letting them insert an image then copying it to each slide OR by copying it to the slide master or one or more layouts.
This will take whatever shapes you have selected and dupe them on each slide in the presentation (so they sit atop anything else on each slide). As they're pasted onto each slide, they're "tagged" so they can be identified later. If you run the macro again, it first deletes any shapes it's tagged, so you don't wind up with lots of duplicates.
Sub DupeAcrossAllSlides()
Dim oShRange As ShapeRange
Dim oSl As Slide
Dim oSh As Shape
Dim oDupeShrange As ShapeRange
Dim x As Long
' Delete any old duped shapes
For Each oSl In ActivePresentation.Slides
For x = oSl.Shapes.Count To 1 Step -1
If Len(oSl.Shapes(x).Tags("Dupe")) > 0 Then
oSl.Shapes(x).Delete
End If
Next
Next
Set oShRange = ActiveWindow.Selection.ShapeRange
oShRange.Copy
For Each oSl In ActivePresentation.Slides
Set oDupeShrange = oSl.Shapes.Paste
For Each oSh In oDupeShrange
oSh.Tags.Add "Dupe", oSh.Name
Next
Next
oShRange.Delete
End Sub

Variable Increase in MS PowerPoint

I've very limited knowledge of PowerPoint but have been asked to create a presentation slide where I would have to click areas on a map and that would change color and increment a number (population). I am able to change the color of the map on click and I'm able to display a bubble but I am not able to increment the population number based on the areas of the map that are clicked.
I've looked at some solutions around here and did some research online but couldn't find anything that would point me in the right direction.
Is there a way to create a variable and pass a number when you click a specific area of the map, which is a Freeform.
Thank you in advance for the help.
You can set each shape's Action Setting to Run Macro: (macro name)
That will run the VBA subroutine called (macro name) when you click on the shape during a slide show.
Mac PowerPoint has a few bugs that keep this from working as smoothly as it does in Windows PowerPoint but the code below works around these issues and works in either version.
Sub IncrementNumber(oSh as Shape)
Dim oSl as Slide
Dim oShTemp as Shape
' oSh.Parent returns a valid reference to the shape's host slide:
Set oSl = ActivePresentation.Slides(oSh.Parent.SlideIndex)
' and oSh.Name works as well
' So we use those two bits to get a reference
' to the clicked shape like so
Set oShTemp = oSl.Shapes(oSh.Name)
With oShTemp
.TextFrame.TextRange.Text = _
Cstr(CLng(oShTemp.TextRange.Text) + 1)
End With
End Sub
About this bit:
Cstr(CLng(oShTemp.TextRange.Text) + 1)
This gets the current text in the shape, converts it from text (string) to a number so we can do arithmetic on it, adds 1 to it, then converts it back to text so we can plug it back into the shape's text.
If you don't know what to do with VBA code examples, there's a tutorial on the PowerPoint FAQ site that I maintain:
How do I use VBA code in PowerPoint
http://www.pptfaq.com/FAQ00033_How_do_I_use_VBA_code_in_PowerPoint.htm

Resizing an image to place into a different sheet, using the default naming convention

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"

Scale / Resize StdPicture in VB6

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.

Load Picture to Microsoft Access 2010 Ribbon from Table

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()">

Resources