How to reset picture back from artistic effect in Excel VBA - excel

I am trying to figure out something. I have a picture in my Excel file. Whenever I click on it I want it to become grayscale so I use the following vba code:
Sheets("Dashboard-3").Shapes("ReportsIcon").Fill.PictureEffects.Insert msoEffectPencilGrayscale
And it works perfectly fine. But then I want it to get back to its original color and formatting when I click again (Which is the Reset Picture button in Excel). unfortunately recording Macro doesnt get that. I use msoEffectNone, msoEffectTypeNone, but doesnt work. Also searched a lot but seems no one has tried to reset the artistic effects back. Does anyone have a clue what should I use?

You don't need to set a different effect, you have to remove it with Delete from the list of PictureEffects that are assigned to the picture. The following Sub shows how to toggle it (if it is present, it is removed, else applied)
Sub toggleEfect(sh As Shape, efecttype As Long)
Dim fe As PictureEffect, found As Boolean
For Each fe In sh.Fill.PictureEffects
If fe.Type = efecttype Then
fe.Delete
found = True
End If
Next
If Not found Then sh.Fill.PictureEffects.Insert efecttype
End Sub
You can call it with
toggleEfect Sheets("Dashboard-3").Shapes("ReportsIcon"), msoEffectPencilGrayscale

Related

Excel VBA - Save Userform Changes

Is it possible to save changes to a Label Caption in a userform in Excel VBA, so that they are permanently saved, and only changed when you enter a new change?
I have checked, that the code is changing the caption, but I cannot get it to stick, so that it is still there next time I open the userform.
Thank you in advance
Private Sub cmdSubmit_Click()
'resets participants email and name
If Me.optProg.Value = True Then
Me.NameLabelProg.Caption = Me.CB_Part.Value
Me.MailLabelProg.Caption = Me.TB_Mail.Value
ElseIf Me.optTester.Value = True Then
Me.MailLabelTest.Caption = Me.CB_Part.Value
Me.NameLabelTest.Caption = Me.TB_Mail.Value
End If
End Sub
Check out this userform example and you'll find answers to many of your questions.
Source of userform
Forgive the lengthy answer initially, but there is a bit of a risk involved with making permanent changes to UserForms through VBA.
In order to change the caption of a Label (or UserForm or any other Control permanently, you will have to "Trust access to the VBA project object model" in order to do it via VBA code. Now, while this is possible it is not usually recommended because it can seriously put a user's PC at Risk should they encounter a Macro developed for nefarious purposes.
(To clarify in case the question is raised, your end user(s) will have to make this Trust setting change on their PC's as well . . . you cannot make the change on your PC, setup the code to work and then hand the file over to another user and have it work on their PC without them making the same change.)
There are methods to do this programmatically, but, this falls into the "nefarious Macro" rabbit hole and would need to be disclosed to the end user you are making this change. . . Research at your own risk.
If you are OK with putting yourself at risk, you can do it using VBA similar to the following snippet I found here. You will have to substitute your UserForm name and Label name as appropriate. I tested it on my own UserForm and it works as expected.
Sub Change_Userform()
ThisDocument.VBProject.VBComponents("Userform1").Designer.Controls("Label1").Caption = "Some new caption text"
End Sub
You will need to do some research on how to "Trust access to the VBA project object model" yourself and understand the risks to do this in order for the above code to work.
If I understand the intent of what you are trying to accomplish correctly though, you could achieve this effect without having to put yourself or your end user(s) at risk.
(Most end user(s) typically would not have direct access to the VBA Designer where they would see the UserForm's un-initialized environment.) To do this, you would have to place your code in the UserForm's event.
The following assumes your Me.optProg.Value and Me.optTester.Value are Option Buttons which a user would change. If you create a "Settings" sheet in the file, you can place values in the cells of this sheet and then hide it so the users do not modify them directly. Then, reference the values of the cells and change the appearances of the Option Buttons at the same time as the UserForm's launch. (Additionally, you can set the Click events of the Option Buttons to change the values of the same cells and provide that change to affect the UserForm's Initialize event when called, but this should get you going in the right direction.)
Sub UserForm_Initialize()
'The Range below is completely up to you.
'Since you are using Boolean True/False, a simple "1" or "0" _
is easy to use to make the changes.
If Thisworkbook.Sheets("Some_Settings").Range("A1").Value = "1" Then
Me.optProg.Value = True
Else
Me.optTester.Value = True
End If
'do some other code here as needed to finish initializing the UserForm
If Me.optProg.Value = True Then
Me.NameLabelProg.Caption = Me.CB_Part.Value
Me.MailLabelProg.Caption = Me.TB_Mail.Value
ElseIf Me.optTester.Value = True Then
Me.MailLabelTest.Caption = Me.CB_Part.Value
Me.NameLabelTest.Caption = Me.TB_Mail.Value
End If
End Sub

Updating userform textboxes in userform frames

I'm trying to create a system within a VBA textbox that modifies the input.
Textboxes along with other options are in frames that can be opened and closed. Done to keep the form readable for other people.
I know it can be done by editing the string solely in code (and have done that to keep working on the project) but I want people to see the edits the code makes.
These updates are inconsistent. I have two textboxes that edit themselves with identical lines of code and they are both set to update themselves once the textbox has been exited. One only updates if something within the frame that it is in gets clicked on again and the other doesn't update at all whether clicking within its frame or outside.
Ideally the moment a textbox gets edited and something else gets clicked on the textbox updates.
Update
Only updates itself if something else like another checkbox in the frame is clicked or selected and it will also then work when clicking outside of the frame. Does anyone know why?
Code for both
Private Sub Pathbox_Change()
End Sub
Private Sub Pathbox_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Dim sDir As String
sDir = S5Int.Pathbox.Text
If Right(sDir, 1) <> "\" Then
S5Int.Pathbox.Text = sDir & "\"
End If
End Sub
The same code for both except the name of the procedure. Frames are also same except for their names. In the form they look something like this:
Form with textboxes
Settings of the elements are also identical
Found a solution last week;
I have just put the trigger of updating on the form itself whenever the form itself is clicked it runs through checks to see what needs to be updated and updates; Its a bit crude but it works quite well. This solution wont work if something else other than the form is clicked but that didnt work either for Textbox1_Exit(etc). Since it only updates the form when the form is in the forefront.
It is Also a bit wasteful of cycles as it runs every single time anything on the form is clicked too but as long as the checks are efficient it should be good enough.
I will keep working on a better solution however when I have time, maybe see if I can get exiting from the frame working like FaneDuru said but something else on the form seems to be blocking that solution for now.

ActiveX textbox shows previous entry

Apologies for not showing my code but after much trial and error I'm thinking the issue I describe could possibly be a textbox property issue rather than coding error or ommission. The code itself works as it should but there is a phenomenom which frustratingly persists.
On a wsheet amongst a number of ActiveX controls I have a textbox and 2 images. They are used for a search function. As you would expect the textbox is for user entry and the images are for 'run search' and 'erase search'. I set the search text as a string.
My issue is when hitting either 'run search' OR 'erase search' the textbox momentarily shows the previous text string. I have set this previous string to "" all over but without success.
This is best observed when setting a search text which will knowingly fail.
The sequence is...
1) Enter 'XXXX' to search
2) Hit 'run search'
3) Search code executes
4) Prior to textbox narrative returning "XXXX not found" it momentarily shows the previous entry, say "AAAA", before returning the correct result.
How can this be prevented?
EDIT
With no response I posted this on Jon Peltier's site at https://peltiertech.com/forms-controls-and-activex-controls-in-excel/#comment-1481602
Kindly he tested and concluded "It looks like an ActiveX thing, and I guess you’re stuck with it."
From tests this phenomenon occurs even when selecting any cell, not only the image controls. In other words it is triggered as soon as the textbox loses focus. Arguably, because it is a momentary change it does not seem possible to trap the text.
I was experiencing a similar problem and raised a question myself, but managed to have more luck in getting some responses, see:
After setting ActiveX textbox to empty value, previous text briefly appears in box before disappearing again
Through the help of the responders I was able to create a work around using Application.SendKeys. Possibly one of the answers might be able to help you in getting around this issue.
For me personally Application.SendKeys was required as this overwrote the value in the text box and refreshed it meaning the previous value was no longer present. For completeness here is a snippet of the code I used:
'Select text box to update
Sheet1.userName.Activate
DoEvents
'Replace value with ""
Sheet1.userName.Application.SendKeys ("")
'Copy above for other textboxes on sheet
Sheet1.emailAddr.Activate
DoEvents
Sheet1.emailAddr.Application.SendKeys ("")
'Change text box currently active to force change values to take place
Sheet1.userName.Activate
I am selecting my text boxes one at a time then using SendKeys("") as a way to emulate the user deleting the current field in the box, after that I switch back to another text box as this is needed to force the refresh of the value.
Being able to force the text boxes to be blank after I was done with the values meant that there were no previous values that could inadvertently appear later on.
Thank you Skenworthy for your suggestion. Over time I kept returning to my issue but without success however your code has formed the basis of a solution.
I only had 1 textbox used as a search input plus 2 buttons, 1 to begin search and the other to clear.
My solution was to create a hidden dummy textbox and each time I wished to make a comment in the search textbox I would use sendkeys to the dummy box. However that was not the final code. Switching focus between the 3 controls became too complex given the type of potential user errors that could be made. So I abandoned the Begin search button relying instead on the Enterkey and the Clear search button.
Now each time I need to return a response message I use the code below immediately prior to clear the search textbox. It has consistently worked without flaw. So, a long time coming, my specific solution seems so simple in hindsight but thank you again for the pointer.
Sub RemovePrevText()
''' use dummy txtbox to clear old message from SearchInput
With Sheets(1)
.txtDummy.Activate
DoEvents
.txtDummy.Application.SendKeys ("")
End With
End Sub

How do you ignore earlier content control using VBA in Microsoft Word?

I have a Word template where I have a checkbox content control in the middle of the document. Once this checkbox is clicked, it triggers some commands using VBA. However, I also have plain text content control and date picker content control earlier on in the document that helps in filling out the template for the user. When these boxes are selected, I keep getting an error message saying "Run-time error 6290 - This property is only available for check box content controls".
My question - is there any way to ignore the earlier content control boxes and only run the code when the checkbox is pressed?
My code at the moment looks something like this:
Private Sub Document_ContentControlOnEnter(ByVal ContentControl As ContentControl)
If (ContentControl.Title = "Checkbox1" And ContentControl.Checked = True) Then
*code in here*
End If
End Sub
So you would think that the code would only get triggered once Checkbox1 is checked... but the earlier text and date fields give me an error code. Anyone know what's going on?
I'm not familiar with "content control" or Word VBA, but in Excel, when coding for the .OnChange event, it's important to make sure the cell passed in to the Sub is (one of) the one(s) you want to work with. I'd assume the same is true here.
My guess is your error is on the
ContentControl.Checked = True
portion of your If statement, so give this a try:
Private Sub Document_ContentControlOnEnter(ByVal ContentControl As ContentControl)
If (ContentControl.Title = "Checkbox1") Then
If ContentControl.Checked = True Then
*code in here*
End IF
End If
End Sub
i.e., make sure you're looking at a checkbox control before testing to see if the box is checked.
VBA does not do conditional short-cutting, so it's going to evaluate all statements in a AND conditional even if the first one is False.

Excel VBA forcing selection of objects after run

I've researched this to death and feel like I'm the only person it's ever happened to.
I have some VBA that:
Creates a copy of 3 sheets to a new wb
In the new wb converts to values, deletes objects (shapes and controls) and all but 3 ranges
Opens an existing third file and sets the contents of three ranges in that to match the new wb
Closes the existing file (saved)
Closes the new wb (saved)
Gives a message box saying complete
At the end of all this, something weird happens with the state of the windows. The selected cell does not appear selected. If I try and click a control afterwards, it selects the object (hence users could drag them). It shouldn't and this is the big problem.
I've tried selecting a cell through code, it throws an error. I had limited success by forcing drawing mode off using Call CommandBars("Drawing").Controls("Select Objects").Execute and activating a specific sheet & selecting a cell. However, even then if I even click on a few cells afterwards, the next time I select a control it will select it as an object rather than click the thing.
I have no idea why and can't find anyone who's seen this before.
Any ideas on what I can do?
Thanks,
Basil
I didn't figure it out entirely, but I did find a fix. Hopefully it works for anyone else who finds this problem.
At the end of the code I added this:
ActiveSheet.Shapes.Range("ctrlExportPrices").Select
ActiveSheet.Range("B8").Select
So it forced a control on the sheet to be selected, and then a cell.
The next time I select the control manually, it clicks it rather than selecting the drawing object.

Resources