VBA - Label lose text after paste - excel

So, I'm trying to create "cards" that the user can move around even when the the workbook is locked. Each card will contain info about a certain project.
The way I'm doing it:
Create a few shapes (an rectangle and a few labels and icons)
Group them
Cut the group
Paste as image
The problem is that when I paste as image, all labels loose their text, they change back to "label1".
If I run the code line by line, they don't lose the text.
I've tried already to add "time" between the cut and paste, adding some lines of code, moving the paste line to a separated sub, and even using Application.Wait(), but nothing worked.
I need to have them as an image (or one solid object - just a group doesn't work), because after the macro is finished, the worksheet is locked back again, and there is another macro to allow the user to move shapes even when the workbook is locked.
Here is a sample to show the problem.
Sub MyCode()
Set wkm = Workbooks(ThisWorkbook.Name)
Set wsm = wkm.Worksheets("TestSheet")
'Just two labels as exemple, the original code has more labels, more icons, and the rounded rectangle)
'The values for the constructors in the original code are defined by the user by a forms
Call GenerateLabel("plaseWork", "Name of the project", 14, 30)
Call GenerateLabel("whyCantYouJustWork", "Name of the user", 42, 30)
wsm.Shapes.Range(Array("plaseWork", "whyCantYouJustWork")).Group.Name = "myGroup"
Set freeSlot = wsm.Range("B10") 'Just a random cell, in the original code there is a function to define the position
Application.CutCopyMode = False
wsm.Shapes("myGroup").Cut
With wsm.Pictures.Paste
.left = freeSlot.left
.top = freeSlot.top
End With
Application.CutCopyMode = False
Set card = wsm.Pictures(wsm.Pictures.Count)
card.Name = "card" & projectName
End Sub
Sub GenerateLabel(labelDescription As String, projectName As String, top As Integer, left As Integer)
Set lbLabel = wsm.OLEObjects.Add(ClassType:="Forms.Label.1")
With lbLabel
.Name = labelDescription
.Object.BackStyle = fmBackStyleTransparent
.Width = 160
.top = top
.left = left
End With
With wsm
.OLEObjects(lbLabel.Name).Object.Caption = projectName
.Shapes(lbLabel.Name).Fill.Transparency = 1
End With
End Sub

What about using shapes with no outline or fill, in place of labels?
Sub MyCode()
Dim wsm As Worksheet, arr(0 To 1), grp As Shape
Set wkm = Workbooks(ThisWorkbook.Name)
Set wsm = wkm.Worksheets("TestSheet")
arr(0) = AddLabel(wsm, "Name of the project", 14, 30).Name
arr(1) = AddLabel(wsm, "Name of the user", 42, 30).Name
Set freeSlot = wsm.Range("B10") 'Just a random cell, in the original code there is a function to define the position
wsm.Shapes.Range(arr).Group.Cut
With wsm.Pictures.Paste
.left = freeSlot.left
.top = freeSlot.top
End With
Set card = wsm.Pictures(wsm.Pictures.Count)
card.Name = "card" & projectName
End Sub
'Add a shape to a worksheet, with the text provided.
' Return the added shape
Function AddLabel(ws As Worksheet, projectName As String, top As Integer, left As Integer)
Dim shp
Set shp = ActiveSheet.Shapes.AddShape(msoShapeRectangle, left, top, 160, 30)
With shp
.Fill.Visible = msoFalse
.Line.Visible = msoFalse
With .TextFrame2.TextRange.Characters
.Text = projectName
.Font.Fill.ForeColor.RGB = vbBlack
.Font.Size = 14
End With
End With
Set AddLabel = shp
End Function

Related

Troubles importing and formatting photos

G'day all, I'm trying to create a button that opens the dialogue box, allows the user to
select a photo from their files,
embeds that file to the particular cell that the button exists in,
and allows it to move and size along with that cell, while maintaining aspect ratio (thanks for the pickup dbmitch)
I have successfully done that using the expression.Insert.Picture() method, but had a rude surprise when I sent the sheet out and all the pictures were replaced with "Photo has been moved, deleted or edited." It seems this method only links the file, which certainly won't work for me, so now I'm trying the much older method of expression.shapes.addPicture(). I think I am successfully adding the photo, but can't seem to get the sizing or locking to cell to work. Please see both attempts below-
Sub GetPic()
Dim fNameAndPath As Variant
Dim img As Picture
fNameAndPath = Application.GetOpenFilename(Title:="Select Picture To Be Imported")
If fNameAndPath = False Then Exit Sub
Set img = ActiveSheet.Pictures.Insert(fNameAndPath)
With img
'Resize Picture to fit in the range....
.Left = ActiveSheet.Range(ActiveSheet.Shapes(Application.Caller).TopLeftCell.Address).Left
.Top = ActiveSheet.Range(ActiveSheet.Shapes(Application.Caller).TopLeftCell.Address).Top
.Width = ActiveSheet.Range(ActiveSheet.Shapes(Application.Caller).TopLeftCell.Address).Width
.Height = ActiveSheet.Range(ActiveSheet.Shapes(Application.Caller).TopLeftCell.Address).Height
.Placement = 1
.PrintObject = True
End With
End Sub
Sub TestPic()
Dim ws As Worksheet, s As Shape
Set ws = ActiveSheet
' Insert the image.
Set s = ws.Shapes.AddPicture(Application.GetOpenFilename(Title:="Please work"), _
False, True, ActiveSheet.Range(ActiveSheet.Shapes(Application.Caller).TopLeftCell.Address).Left, _
ActiveSheet.Range(ActiveSheet.Shapes(Application.Caller).TopLeftCell.Address).Top, _
ActiveSheet.Range(ActiveSheet.Shapes(Application.Caller).TopLeftCell.Address).Width, _
ActiveSheet.Range(ActiveSheet.Shapes(Application.Caller).TopLeftCell.Address).Height)
' Use picture's height and width.
End Sub
I was able to get this code to run in Excel 2016 VBA. You don't say where you're running this from but I assume Application.Caller is not from a module? Maybe a Userform?
Here's what worked for me - hopefully you can use it
Sub TestPic()
Dim ws As Worksheet, s As Shape
Dim sngLeft As Single, sngRight As Single, sngTop As Single, sngWidth As Single
Set ws = ActiveSheet
' Insert the image.
With ActiveCell.Cells
sngLeft = .Left
sngTop = .Top
sngWidth = .Width
sngheight = .Height
End With
Set s = ws.Shapes.AddPicture(Application.GetOpenFilename(Title:="Please work"), _
msoFalse, msoTrue, sngLeft, sngTop, sngWidth, sngheight)
s.Placement = xlMoveAndSize ' move and resize when cell dimensions change
'ActiveSheet.Range(ActiveSheet.Shapes(Application.Caller).TopLeftCell.Address).Left, _
'ActiveSheet.Range(ActiveSheet.Shapes(Application.Caller).TopLeftCell.Address).Top, _
'ActiveSheet.Range(ActiveSheet.Shapes(Application.Caller).TopLeftCell.Address).Width, _
'ActiveSheet.Range(ActiveSheet.Shapes(Application.Caller).TopLeftCell.Address).Height)
' Use picture's height and width.
End Sub

How can I change the shape size of a shape by clicking another shape?

I have multiple shapes that when clicked it's doing things in my Excel sheet (my code below).
But apart from these things I want to change the size of a shape that is positioned 2 cells to the right of the shape I'am clicking.
How can I do this without referring to the name of the shape I want to resize?
This is my code.
Sub ArrowClick()
With ActiveSheet.Shapes(Application.Caller).TopLeftCell
.EntireRow.Borders(xlEdgeBottom).LineStyle = xlNone
With .EntireRow.Offset(1, 0).Resize(9)
.EntireRow.Hidden = Not .Hidden
End With
End With
End Sub
Please, use the next way. It will select the shape on the second column of the clicked shape row and double its width:
Sub ArrowClick()
Dim nextSh As Shape
Const sizeW As Double = 45 'use there your usual real width
Const sizeH As Double = 14 'use there your usual real height
With ActiveSheet.Shapes(Application.Caller).TopLeftCell
.EntireRow.Borders(xlEdgeBottom).LineStyle = xlNone
With .EntireRow.Offset(1, 0).Resize(9)
.EntireRow.Hidden = Not .Hidden
End With
Set nextSh = findNextSh(.Offset(0, 2).Address)
If Not nextSh Is Nothing Then
nextSh.placement = xlMove 'set the placemeny property to `Move but don't size with cells
If nextSh.width = sizeW Then
nextSh.width = sizeW * 2 'use here what size you need for changing the initial sizes
nextSh.height = sizeH * 1.2
Else
nextSh.width = sizeW: nextSh.height = sizeH
End If
End If
End With
End Sub
Function findNextSh(strRange As String) As Shape
Dim sh As Shape
For Each sh In ActiveSheet.Shapes
If sh.TopLeftCell.Address = strRange Then
Set findNextSh = sh: Exit Function
End If
Next sh
End Function

#VBA #Excel - Stretched and shifted pictures

I'm working on a project using VBA with Excel. By clicking a button, we generate an array. One line refers to one product. The information is stored in each column (column A = reference, column B = name...). The generation is made with some code using VBA.
The problem concerns the pictures. I managed the shape of the pictures, so they are placed in the cell, with a certain height, width, placement...
When I generate the array from my computer, there's no problem, the pictures are placed perfectly.
When the array is generated from another computer, the pictures look stretched and shifted. That's it from the 12th line to the end (but the first 11 lines are okay). I don't understand why it starts from the 12th line because the code is exactly the same for every line of the array. And above all, I don't understand why the array isn't well generated on every computer.
The Excel version is the same and the pictures options too.
Have you heard about something like that?
Thanks a lot for your comments!
Here's the code:
Function SetImageViewer(Ref As String, Cell As Range) As String
Dim cmt As Comment
Dim sPicName As String
Dim ImageCell As Range
Dim OrderFormWS As Worksheet
sPicName = GetParameter("PicturesPath") & "\" & Ref & ".jpg"
Set ImageCell = Cell.MergeArea
Set OrderFormWS = ThisWorkbook.Sheets("OrderForm")
sPicFile = Dir(sPicName)
If sPicFile <> vbNullString Then
Set Pic = OrderFormWS.Shapes.AddPicture(sPicName, linktofile:=msoFalse, SaveWithDocument:=msoCTrue, Left:=0, Top:=0, Width:=0, Height:=0)
With Pic
.LockAspectRatio = msoTrue
.Left = ImageCell.Left + 5
.Top = ImageCell.Top + 5
.Width = 40
.Height = 40
.Placement = xlMoveAndSize
End With
Set cmt = Cell.Comment
If cmt Is Nothing Then Set cmt = Cell.AddComment()
cmt.Text " "
cmt.Shape.Fill.UserPicture sPicName
cmt.Shape.Height = 300
cmt.Shape.Width = 300
SetImageViewer = ChrW(&H25BA)
Else
Set cmt = Cell.Comment
If Not cmt Is Nothing Then cmt.Delete
SetImageViewer = "No picture"
End If
End Function

Excel VBA Resize picture in a certain range [duplicate]

This question already has answers here:
How to resize all images on a worksheet?
(2 answers)
Closed 3 years ago.
Ok i have an image that a 3rd part software is placing into an excel file. in order to get the resolution needed it has to be sized much larger than needed. It will always be placed in the same location and be a specific size. I need to resize it. Ideally it would be automatic when the excel file opens but i think any vba code would end up acting before the information is inserted, but if there was a small delay that would be cool too. Alternatively i could make do with a button that runs a bit of code. The code below works, but only when the picture is specifically named "Picture 179" which it won't be ever again or at least until the counter recycles.
The image is inserted at Cell A45 specifically but it extends through roughly cell AZ60.
Here is what i've got that doesn't work.
Private Sub Resize_Graph_Click()
ActiveSheet.Shapes.Range(Array("Picture 179")).Select
Selection.ShapeRange.Height = 104.4
Selection.ShapeRange.Width = 486.72
End Sub
You still need to work out when to resize the picture, but the example code below shows how you can specifically access a picture where the Top-Left corner of the picture is located within a given cell.
Option Explicit
Sub TestMe()
Dim thePicture As Shape
Set thePicture = GetPictureAt(Range("A45"))
If Not thePicture Is Nothing Then
Debug.Print "found it! (" & thePicture.Name & ")"
With thePicture
.Height = 75
.Width = 75
Debug.Print "resized to h=" & .Height & ", w=" & .Width
End With
Else
Debug.Print "couldn't find the picture!"
End If
End Sub
Private Function GetPictureAt(ByRef thisCell As Range) As Shape
Dim thisCellTop As Long
Dim thisCellBottom As Long
Dim thisCellLeft As Long
Dim thisCellRight As Long
With thisCell
thisCellTop = .Top
thisCellLeft = .Left
thisCellBottom = thisCellTop + .Height
thisCellRight = thisCellLeft + .Width
End With
Dim shp As Variant
With Sheet1
For Each shp In .Shapes
If shp.Type = msoPicture Then
If (shp.Top >= thisCellTop) And (shp.Top <= thisCellBottom) Then
If (shp.Left >= thisCellLeft) And (shp.Left <= thisCellRight) Then
Set GetPictureAt = shp
Exit Function
End If
End If
End If
Next shp
End With
End Function
Here is what i settled on.
Private Sub Resize_Graph_Click()
'resize all shapes
Dim s As Shape
Dim ws As Worksheet
Set ws = ActiveSheet
For Each s In ActiveSheet.Shapes
s.LockAspectRatio = msoFalse
s.Width = 491.72
s.Height = 106.56
Next s
'set header shapes and button back to original size
ActiveSheet.Shapes.Range(Array("Company Label")).Select
Selection.ShapeRange.Height = 43.92
Selection.ShapeRange.Width = 131.76
ActiveSheet.Shapes.Range(Array("Product Label")).Select
Selection.ShapeRange.Height = 49.68
Selection.ShapeRange.Width = 134.64
ActiveSheet.Shapes.Range(Array("Resize_Graph")).Select
ActiveSheet.Shapes("Resize_Graph").Height = 38.16
ActiveSheet.Shapes("Resize_Graph").Width = 105.12
'keep button from moving after changing shape back and forth
ActiveSheet.Shapes.Range(Array("Resize_Graph")).Select
ActiveSheet.Shapes("Resize_Graph").Left = 380
ActiveSheet.Shapes("Resize_Graph").Top = 5
ActiveWorkbook.Close Savechanges:=True
End Sub

Setting the font size in a shape

I have the following macro which is supposed to create a box linking to a certain worksheet in the workbook, on each sheet of the workbook:
Option Explicit
Sub gndhnkl()
Dim ws As Worksheet
Dim sh As Shape
For Each ws In ThisWorkbook.Worksheets
If InStr(1, ws.Name, "Summering", vbBinaryCompare) <= 0 Then
For Each sh In ws.Shapes
sh.Delete
Next sh
Call Macro1(ws)
End If
Next ws
End Sub
Sub Macro1(ws As Worksheet)
Dim venstre As Double, topp As Double, breidde As Double, høgde As Double
Dim sh As Shape
venstre = ws.Range("B16").Left
topp = ws.Range("B16").Top
breidde = 110
høgde = 68
Set sh = ws.Shapes.AddShape(msoShapeRoundedRectangle, venstre, topp, breidde, høgde)
With sh.TextFrame2.TextRange
.Characters.Text = "Til summering, person"
.Font.Size = 13
.ParagraphFormat.Alignment = msoAlignCenter
.Parent.VerticalAnchor = msoAnchorMiddle
End With
ws.Hyperlinks.Add Anchor:=sh, Address:="", SubAddress:=Replace(Summering_person.Range("A1").Address(external:=True), "[" & ThisWorkbook.Name & "]", "", 1, -1, vbBinaryCompare)
End Sub
For the most part it works just like I expect it too, but for some reason the font size in the added shape is not set to 13 as I expect, but remains 11.
I.e. it seems that the line .Font.Size = 13 (sh.TextFrame2.TextRange.Font.Size = 13) is not executed.
Where is my mistake here, and what do I need to do in order for the macro to set the font size for the shape?
You have to change the order, first set the font size (and any other font properties) before you write the text. Once the text is set, it's getting trickier to change the font - every character of the TextFrame may have it's own characteristics.
.Font.Size = 13
.Characters.Text = "Til summering, person"
Update The comment of SJR is right, when using the TextFrame rather than TextFrame2, you can set the font properties of the whole text as once after the text was written.

Resources