Is there a way to update the alt text for multiple form control checkboxes at once using Excel VBA? I have about 20 check boxes on a worksheet {"Sheet1"} (Check Box 1, Check Box 2, ... Check Box 20) and need to change the text for all to = "In Progress". Thanks in advance!
"Finding and Replacing in Text Boxes
by Allen Wyatt
(last updated July 20, 2019)
Sub TextBoxReplace()
Dim shp As Shape
Dim sOld As String
Dim sNew As String
'Change as desired
sOld = "Old string"
sNew = "New string"
On Error Resume Next
For Each shp In ActiveSheet.Shapes
With shp.TextFrame.Characters
.Text = Application.WorksheetFunction.Substitute( _
.Text, sOld, sNew)
End With
Next
End Sub
This macro steps through all the shapes in the worksheet (text boxes are shapes) and then replaces whatever is in the sOld variable with whatever is in the sNew variable."
From excelribbon.tips.net
Disregard; I found a solution! ^_^
https://excelribbon.tips.net/T009264_Finding_and_Replacing_in_Text_Boxes.html
Related
I'm trying to create a macro that will select any slide that contains a keyword in the title, but not getting anywhere. The ppt includes different frontpages, disclaimers and content slides and the idea is to add keywords to the titles of each slide and get the macro to select and export the selected slides to PDF.
I've got the export part working, but have the enter the slide numbers manually.
I got the code below from a similar question, but can't rewrite it to select the slides instead of presenting the answers as a MsgBox. Can somebody help, please?
Sub FindText()
Dim sld As Slide, shp As Shape, list As String, myPhrase As String
myPhrase = InputBox("enter a phrase", "Search for what?")
For Each sld In Application.ActivePresentation.Slides
For Each shp In sld.Shapes
If shp.HasTextFrame Then
If Left(shp.Name, 5) = "Title" Then
If Not shp.TextFrame.TextRange.Find(FindWhat:=myPhrase) Is Nothing Then
If list = "" Then list = sld.Name Else list = list & ", " & sld.Name
End If
End If
End If
Next shp
Next sld
MsgBox list
End Sub
My full code, using Steve's solution, if anyone is trying to solve the same problem:
Sub SelectedSlidesToPDF()
Dim sld As Slide, shp As Shape, list As String, myPhrase As String
myPhrase = "WhatYouLookFor"
For Each sld In Application.ActivePresentation.Slides
' FIRST, hide the slide:
sld.SlideShowTransition.Hidden = True
For Each shp In sld.Shapes
If shp.HasTextFrame Then
If Left(shp.Name, 5) = "Title" Then
If Not shp.TextFrame.TextRange.Find(FindWhat:=myPhrase) Is Nothing Then
' UNHIDE the slides that contain your keywords
sld.SlideShowTransition.Hidden = False
End If
End If
End If
Next shp
Next sld
'EXPORT slides
ActivePresentation.ExportAsFixedFormat ActivePresentation.Path & "\" & "MySelectedSlides " & Format(DateSerial(Year(Date), Month(Date) - 1, 1), "yyyy-mm") & ".pdf", ppFixedFormatTypePDF, ppFixedFormatIntentPrint, RangeType:=ppShowAll
' UNIHDE all slides in presentation
For Each sld In ActivePresentation.Slides
sld.SlideShowTransition.Hidden = msoFalse
Next sld
End Sub
By default, when you save as PDF, the PDF won't include any slides that are hidden, so you can simply hide all the slides first, then UNHIDE any that you want to include in the PDF. While I haven't done this here, you'll want to UNHIDE all the slides again after saving to PDF.
For Each sld In Application.ActivePresentation.Slides
' FIRST, hide the slide:
sld.SlideShowTransition.Hidden = True
For Each shp In sld.Shapes
If shp.HasTextFrame Then
If Left(shp.Name, 5) = "Title" Then
If Not shp.TextFrame.TextRange.Find(FindWhat:=myPhrase) Is Nothing Then
' UNHIDE the slides that contain your keywords
sld.SlideShowTransition.Hidden = False
End If
End If
End If
Next shp
Next sld
I am trying to use PowerShell to pro-grammatically update notes in PowerPoint slide notes. Being able to do this will save tremendous amounts of time. The code below allows me to edit the notes field with PowerShell but it messes up the format each time.
$PowerpointFile = "C:\Users\username\Documents\test.pptx"
$Powerpoint = New-Object -ComObject powerpoint.application
$ppt = $Powerpoint.presentations.open($PowerpointFile, 2, $True, $False)
foreach($slide in $ppt.slides){
if($slide.NotesPage.Shapes[2].TextFrame.TextRange.Text -match "string"){
$slide.NotesPage.Shapes[2].TextFrame.TextRange.Text = $slide.NotesPage.Shapes[2].TextFrame.TextRange.Text -replace "string","stringreplaced"
}
}
Sleep -Seconds 3
$ppt.Save()
$Powerpoint.Quit()
For example, right now it will iterate through each slide's notes and update the word string to stringreplaced but then the entire notes text becomes bold. In my notes I have a single word at the top of the notes that is bold and then text below it. For example, a note on a slide my look like this:
Note Title
Help me with this string.
After PowerShell updates the notes field it saves it to a new .pptx file but the note now looks like this:
Note Title
Help me with this stringreplaced.
Any ideas on how to update slide notes without messing up any formatting found in the notes? It only messes up formatting for slides the script updates.
When you change the entire text content of a textrange in PPT, as your code's doing, the changed textrange will pick up the formatting of the first character in the range. I'm not sure how you'd do this in PowerShell, but here's an example in PPT VBA that demonstrates the same problem and shows how to use PPT's own Replace method instead to solve the problem:
Sub ExampleTextReplace()
' Assumes two shapes with text on Slide 1 of the current presentation
' Each has the text "This is some sample text"
' The first character of each is bolded
' Demonstrates the difference between different methods of replacing text
' within a string
Dim oSh As Shape
' First shape: change the text
Set oSh = ActivePresentation.Slides(1).Shapes(1)
With oSh.TextFrame.TextRange
.Text = Replace(.Text, "sample text", "example text")
End With
' Result: the entire text string is bolded
' Second shape: Use PowerPoint's Replace method instead
Set oSh = ActivePresentation.Slides(1).Shapes(2)
With oSh.TextFrame.TextRange
.Replace "sample text", "example text"
End With
' Result: only the first character of the text is bolded
' as it was originally
End Sub
I've created a form within Access which uses a cross-tab query as its data source.
The column headings for the query are 1, 2, 3, 4 and 5 representing week numbers.
The values display items such as 3/3 = 100.00% or 0/13 = 0.00% or 3/14 = 21.00%.
I've added conditional formatting to the text boxes on the form.
Expression Is Right([2],7)="100.00%" works and displays the figure in bold red when the percentage is 100.
Expression is Val(Right([2],7))=100 also works - converting the text value to a numeric value.
The problem I'm having is that I'm not always looking for 100% - it depends on the value within a table. What I'm trying to do is
Val(Right([2],7))=(SELECT ParamValue*100 FROM tbl_System WHERE Param='SampleSize') - this doesn't work.
Neither does:
Eval(Val(Right([2],7))=(SELECT ParamValue*100 FROM tbl_System WHERE Param='SampleSize'))
or
Val(Right([2],7))=EVAL(SELECT ParamValue*100 FROM tbl_System WHERE Param='SampleSize')
or
Val(Right([2],7))=DLookUp("ParamValue","tbl_System","Param= 'SampleSize'")*100
or
Val(Right([2],7))=Eval(DLookUp("ParamValue","tbl_System","Param= 'SampleSize'")*100)
The SQL for the cross-tab query is:
TRANSFORM NZ(Sum(Abs([Include])),0) & "/" & NZ(Count(*),0) & " = " &
FormatPercent(NZ(Round(Sum(Abs(Include))/Count(*),2),0),2)
SELECT tbl_TMP_PrimaryDataSelection.TeamMember
FROM tbl_TMP_PrimaryDataSelection
GROUP BY tbl_TMP_PrimaryDataSelection.TeamMember
PIVOT tbl_TMP_PrimaryDataSelection.WeekNum In (1,2,3,4,5)
I don't think you can use a function in there, be it system or user-defined.
But you can define the FormatCondition dynamically at runtime, like this:
Dim txtFld As TextBox
Dim objFrc As FormatCondition
Dim strExpr As String
Set txtFld = Me!myTextBox
' Remove existing FormatConditions
txtFld.FormatConditions.Delete
' The dynamic expression
strExpr = "Val(Right([2],7))=" & DLookUp("ParamValue","tbl_System","Param='SampleSize'")*100
' Assign a new FormatCondition to text box
Set objFrc = txtFld.FormatConditions.Add(acExpression, , strExpr)
' Set the format
objFrc.ForeColor = &HFF0000
This example simply removes and recreates all FormatConditions. If you have a fixed number of conditions, you can also use the FormatCondition.Modify method (see online help).
Edit:
The final code I have used executes on the Form_Load event and adds a format to each of the five weekly text boxes:
Private Sub Form_Load()
Dim aTxtBox(1 To 5) As TextBox
Dim x As Long
Dim oFrc As FormatCondition
Dim sExpr As String
With Me
Set aTxtBox(1) = .Wk1
Set aTxtBox(2) = .Wk2
Set aTxtBox(3) = .Wk3
Set aTxtBox(4) = .Wk4
Set aTxtBox(5) = .Wk5
For x = 1 To 5
aTxtBox(x).FormatConditions.Delete
sExpr = "Val(Right([" & x & "],7))>=" & DLookup("ParamValue", "tbl_System", "Param='SampleSize'") * 100
Set oFrc = aTxtBox(x).FormatConditions.Add(acExpression, , sExpr)
oFrc.ForeColor = RGB(255, 0, 0)
Next x
End With
End Sub
Edit 2
Yes, defining FormatConditions via VBA is especially useful when dealing with multiple controls in a loop. You can do this in Design View too and save the FormatConditions permanently, simply to avoid going through the FormatConditions dialogs one by one. Or if the customer later decides that he'd rather have a different color. :)
Note: You could use Set aTxtBox(x) = Me("Wk" & x) in the loop. But actually you don't need multiple TextBox variables, you can simply re-use it.
I am extremely new to all of this, and whilst I have tried searching I cant find anything that has helped me achieve what I am after.
I have a form in VB with the following:
1 x tabcontrol
10 x checkboxes which sit in various tabs on the tab control
1 x listbox
When i tick any of the check boxes, I want their text to be added to the listbox, and when I untick, their text to be taken from the listbox.
I can achieve this very easily using if statements for the changedcheck event for each checkbox but I have to do that for every single checkbox which isn't very efficient as potentially i could have 20,30 40+ check boxes. Plus if I add one at a later stage I would have to remember to add its code.
Ideally i want a method that's says: check all the checkboxes in tabcontrol if there value is true write their text to a string, if there value is false, take there text from the string. put the string in the listbox.
I started with something like this...
Dim chk As CheckBox
Dim txt As String = ""
For Each chk In TabControl1.Controls
If chk.Checked = True Then
txt = txt + chk.Text +vbCrLF
Else
txt = replace(txt, chk.text + vbCrLf, "")
End If
Next
End Sub
First problem is that the above obviously doesn't work! so any guidance there is appreciated - i put it together from reading scraps from other code.
Second problem is, i can't get my head round how the list box will be updated, as previously i was using the CheckedChanged event for each control, which if i do what i want, then there wont be a specific CheckedChanged event, as it could be any of the checkboxes (hopefully that makes sense!). I don't want to have to press a button to add the checked checkboxes to the listbox, i want it to be dynamic
any help is very much appreciated.
For your first problem add
Dim chk As Control
Dim txt As String = ""
For Each chk In TabControl1.Controls
If TypeOf chk Is CheckBox
If DirectCast(chk, CheckBox).Checked = True Then
txt = txt + chk.Text +vbCrLF
Else
txt = replace(txt, chk.text + vbCrLf, "")
End If
End If
Next
End Sub
For your second problem in CheckedChanged event you can do something like this:
Private Sub OnCheckedChanged(sender as Object, e as EventArgs) _
Handles CheckBox1.CheckedChanged
Dim chk As CheckBox = TryCast(s, CheckBox)
Dim txt as string
If c.Checked = True Then
txt = chk.Text
EndIf
End Sub
Something that I would assume comes up a lot...
I'd like to know if there's a way to, in Access' Conditional Formatting, format all blank fields. In my case, all fields generally need to be entered, but not in all cases. So, instead of writing a bunch of conditional code to restrict the user to writing it in there, I just want some red backgrounds in my fields as a reminder "hey, there's nothing in here.. sure that's what you wanted?"It's on a tablet so Message Boxes would be annoying. So conditional formatting it is. I know you can have "Is Null([Field]) but that requires me to go through my 20+ forms on 30+ fields and ensure proper field names etc, then type the condition for them individually. Is there a way I can simply multi-select my fields, do a conditional format on Multiple, and use maybe "Is Equal To: NULL"?
I've tried "equal to: Null" and it doesn't work.. nor does "equal to: "" " (using the Access constants). Ideas why? Or how I can get around this? Also, it's only necessary for non-touched fields, so if the user starts to type then deletes back to blank, I don't care; it can stay unformatted or go back to red, so if there's a better way to do this I'm all eyes.
EDIT: I've started doing some VBA code which I will paste into all my forms:
Private Sub Form_Load()
Dim ctl As Control
Dim reqCol As Long
Dim focusCol As Long
Dim doneCol As Long
Dim format As FormatCondition
reqCol = RGB(246, 180, 180)
focusCol = RGB(252, 249, 238)
doneCol = RGB(255, 255, 255)
For Each ctl In Me.Controls
With ctl
Me.Controls(ctl.Name).FormatConditions.Delete 'Delete the existing conditions.
Me.Controls(ctl.Name).BackColor = doneCol 'Set the background color to the done color.
Select Case .ControlType
Case acTextBox
'Create the format objects.
format = Me.Controls(ctl.Name).FormatConditions.Add(acFieldValue, acEqual, "")
format = Me.Controls(ctl.Name).FormatConditions.Add(acFieldHasFocus)
'Format the filled in boxes (ie set back to red)
With Me.Controls(ctl.Name).FormatConditions(0)
.BackColor = reqCol
.Enabled = True
End With
'Format the current field color (ie set to beige)
With Me.Controls(ctl.Name).FormatConditions(1)
.BackColor = focusCol
.Enabled = True
End With
End Select
End With
Next ctl
End Sub
Problem is that FormatConditions.Add(acFieldValue, acEqual, "") doesn't work for the same reason... how do I get around this? Seeing as VBA and the built-in conditions are both flawed, seems like a bug. Or I'm missing something right in front of me..
In Access 2016 I was unable to find the default formatting option that is the solution provided by #SeanC. Instead I found that to get my Combo Box to format properly I had to use an Expression with ISNULL.
Set default format to the way to want zero length data to appear.
use
Field Value Is greater than ''
for the conditional formatting and set that format to how it should appear with text in the field.
You can select multiple fields with Shift+click in design view to select all the appropriate fields that this needs to be applied to
Solved. Put this in my forms (might look into making it a module; new to this, not sure how yet)
Private Sub Form_Load()
On Error Resume Next
Dim ctl As Control
Dim reqCol As Long
Dim focusCol As Long
Dim doneCol As Long
Dim format As FormatCondition
Dim expr As String
reqCol = RGB(246, 180, 180)
focusCol = RGB(252, 249, 238)
doneCol = RGB(255, 255, 255)
For Each ctl In Me.Controls
With ctl
'Delete the existing formatting
Me.Controls(ctl.Name).FormatConditions.Delete
Me.Controls(ctl.Name).BackColor = doneCol
Select Case .ControlType
Case acTextBox
expr = "IsNull(" & ctl.Name & ") = True"
'Create the format objects.
format = Me.Controls(ctl.Name).FormatConditions.Add(acFieldHasFocus)
format = Me.Controls(ctl.Name).FormatConditions.Add(acExpression, , expr)
'Format the filled in boxes (ie set back to focus color)
With Me.Controls(ctl.Name).FormatConditions(0)
.BackColor = focusCol
.Enabled = True
End With
'Format the current field color (ie set to required color)
With Me.Controls(ctl.Name).FormatConditions(1)
.BackColor = reqCol
.Enabled = True
End With
End Select
End With
Next ctl
End Sub
The trick was how to enter it into FormatConditions.Add(...). Works exactly how I'd like it to now.