Concatenate hyperlink in Powerpoint VBA - vba

I am trying to concatenate a URL with many different parts(variables) added to the end of the URL.
I have a button and when you click the button it will takes you to the a specific site using the slide index of the current slide.
When the button is click I want it to go to "google.com/p" + Slide.Index + slide.ID + ActivePresentation.fileName
I know the syntax aren't correct but hopefully you get the GIST.
Currently I have this code:
Private Sub CommandButton21_Click()
Dim projId AS Integer = 617
Dim URL AS String = "www.google.com"
Dim coID = "m01"
Dim coTitle AS String = "New CC Project"
Dim oSl As Slide
Dim pgId
ActivePresentation.FollowHyperlink _
Address:="http://google.com/p" + oSl.SlideID
NewWindow:=True, AddHistory:=True
End Sub
Thanks in advance

This should get you a bit closer:
Private Sub CommandButton21_Click()
' You can't assign values to variables at the same time
' as you DIM them; you CAN do so with Constants:
Const projId As Integer = 617
Const URL As String = "www.google.com"
Const coID As String = "m01"
Const coTitle As String = "New CC Project"
Dim oSl As Slide
'Dim pgId
' You can't just refer to oSl; you have to first tell it WHICH slide
Set oSl = ActivePresentation.Slides(1) ' or whatever slide you want
ActivePresentation.FollowHyperlink _
Address:="http://google.com/p" & oSl.SlideID, _
NewWindow:=True, _
AddHistory:=True
End Sub

& is always evaluated in a string context, while + may not concatenate if one of the operands is no string:
Private Sub CommandButton21_Click()
Dim projId AS Integer
Dim URL AS String = "www.google.com"
Dim coID = "m01"
Dim coTitle AS String = "New CC Project"
Dim oSl As Slide
Dim pgId
projId = 617
ActivePresentation.FollowHyperlink _
Address="http://google.com/p" & oSl.SlideID
NewWindow=True
AddHistory=True
End Sub

I have fixed the issue, view the code below!
Sub CommandButton21_Click()
Dim sl As slide
Dim projId As Integer
Dim coID As String
Dim URL As String
Dim coTitle As String
Dim pgId
URL = "www.google.com"
projId = 617
coID = "m01"
coTitle = "New CC Project"
Set sl = SlideShowWindows(1).View.slide
ActivePresentation.FollowHyperlink _
Address:=URL & projId & "&coIdent=" & coID & "&coTitle=" & coTitle & "&pgIdent=" & sl.slideId & "&pgTitle=" & sl.slideId & "&pageFileName=" & ActivePresentation.FullName & "&pageOrder=" & sl.SlideIndex, _
NewWindow:=True, AddHistory:=True

Related

Powerpoint VBA actively select slide range based on string in textbox

I want to scan thorough a slide deck for text boxes containing a search string and leave the active presentation with Active selected slides.
*** I can search ok...>> Creating a list of slides with my text on
Function FindSlidesWithText(ByVal Owner As String) As String
Dim oSl As Slide
Dim oShp As Shape
Dim strSearch As String
Dim i As Integer
Dim slideList As String
If Owner = "" Then
strSearch = InputBox("Enter the text to search for:")
Else
strSearch = Owner
End If
Dim SomeoneSlides As String
SomeoneSlides = ""
SomeoneSlides = ""
For Each oSl In ActivePresentation.Slides
For Each oShp In oSl.Shapes
If oShp.HasTextFrame Then
If InStr(1, oShp.TextFrame.TextRange.Text, strSearch, vbTextCompare) > 0 Then
slideList = slideList & "Slide " & oSl.SlideNumber & ": " & oShp.TextFrame.TextRange.Text & vbCrLf
SomeoneSlides = SomeoneSlides & oSl.SlideNumber & ","
End If
End If
Next
Next
'we now have "search" unique slides.
MsgBox slideList
End Function
*** I note the following works as I want - leaving my in power points seeing highlight boxes around the slides 1,2,5
Dim r1 As SlideRange
Set r1 = ActivePresentation.Slides.Range(Array(1,2, 5)) 'this works
r1.Select
*** However, when i try to create this programmatically i fail (only highlighting the last slide in the array)
'Call SelectSlides("1,2,") '(output from the search)
Sub SelectSlides(YourSlideList As String)
Dim slideArr() As String
'Dim slideNum As Integer
Dim selAry As String
ActiveWindow.ViewType = PpViewType.ppViewNormal
ActiveWindow.Panes(1).Activate
slideArr = Split(YourSlideList, ",")
Dim r1 As SlideRange
For i = 0 To (UBound(slideArr) - 1)
slideNum = CInt(slideArr(i))
selAry = selAry & slideNum
'For all slides selected - modify as needed....
With ActivePresentation.Slides.Range(slideNum)
'Ignore the default background settings.
.FollowMasterBackground = False
'And add a new background color and effect.
.Background.Fill.PresetGradient msoGradientHorizontal, 1, msoGradientDaybreak
End With
Set r1 = ActivePresentation.Slides.Range(Array(slideNum)) 'this works
Next
r1.Select
End Sub
'///this is now working
Sub SelectSlides(YourSlideList As String)
Dim slideArr() As String
'Dim slideNum As Integer
Dim selAry As String
Dim selAry2(99) As Long
ActiveWindow.ViewType = PpViewType.ppViewNormal
ActiveWindow.Panes(1).Activate
slideArr = Split(YourSlideList, ",")
' slideArr2() = Split(YourSlideList, ",")
For i = 0 To (UBound(slideArr) - 1)
slideNum = CInt(slideArr(i))
selAry = selAry & slideNum
selAry2(i) = slideNum
'For all slides selected - modify as needed....
With ActivePresentation.Slides.Range(slideNum)
'Ignore the default background settings.
.FollowMasterBackground = False
'And add a new background color and effect.
.Background.Fill.PresetGradient msoGradientHorizontal, 1, msoGradientDaybreak
End With
Next
Dim r1 As SlideRange
Set r1 = ActivePresentation.Slides.Range(selAry2)
r1.Select
End Sub

MS Word populate text after is inserted via VBA form

I have created word macro enabled template.
At opening form pops-up and user can fill in form. After pressing OK bookmarks inside document are updated and shown.
What I need is to populate entered values trough entire document on multiple locations. I have tried cross-referencing bookmarks but they are not updated with values entered in form.
image of opening form
Private Sub cancelBut_Click()
stInfo.Hide
End Sub
Private Sub Label11_Click()
End Sub
Private Sub OKbut_Click()
Dim katcest As Range
Set katcest = ActiveDocument.Bookmarks("katcest").Range
katcest.Text = Me.TextBox1.Value
Dim katopcina As Range
Set katopcina = ActiveDocument.Bookmarks("katopcina").Range
katopcina.Text = Me.TextBox2.Value
Dim zkcest As Range
Set zkcest = ActiveDocument.Bookmarks("zkcest").Range
zkcest.Text = Me.TextBox3.Value
Dim zkopcina As Range
Set zkopcina = ActiveDocument.Bookmarks("zkopcina").Range
zkopcina.Text = Me.TextBox4.Value
Dim zkulozak As Range
Set zkulozak = ActiveDocument.Bookmarks("zkulozak").Range
zkulozak.Text = Me.TextBox5.Value
Dim povrsina As Range
Set povrsina = ActiveDocument.Bookmarks("povrsina").Range
povrsina.Text = Me.TextBox6.Value
Dim vlasnik As Range
Set vlasnik = ActiveDocument.Bookmarks("vlasnik").Range
vlasnik.Text = Me.TextBox7.Value
Dim vladresa As Range
Set vladresa = ActiveDocument.Bookmarks("vladresa").Range
vladresa.Text = Me.TextBox8.Value
Dim datocevida As Range
Set datocevida = ActiveDocument.Bookmarks("datocevida").Range
datocevida.Text = Me.TextBox9.Value
Dim klasa As Range
Set klasa = ActiveDocument.Bookmarks("klasa").Range
klasa.Text = Me.TextBox10.Value
Dim urbroj As Range
Set urbroj = ActiveDocument.Bookmarks("urbroj").Range
urbroj.Text = Me.TextBox11.Value
Me.Repaint
Dim strDocName As String
Dim intPos As Integer
' Find position of extension in file name
strDocName = ""
intPos = InStrRev(strDocName, ".")
If intPos = 0 Then
' If the document has not yet been saved
' Ask the user to provide a file name
strDocName = InputBox("Upisi naziv " & _
"vaseg dokumenta.")
Else
' Strip off extension and add ".txt" extension
strDocName = Left(strDocName, intPos - 1)
strDocName = strDocName & ".docx"
End If
' Save file with new extension
ActiveDocument.SaveAs2 FileName:=strDocName, _
FileFormat:=wdFormatDocumentDefault
stInfo.Hide
infoForm.Show
End Sub

Multiple Input Boxes to Create Different Emails

Here is what I have been given to try and create:
User creates an email a few times per week and has to re-type everything, a request for employee updates, with up to 5 people on it. Easy enough to create in VBA, except that the employees could change each time. So there could be just 1 person, or 2, or 3, etc...and each time it could be a different mix of the employees. They want input boxes that would prompt how many employees for the email, then based on that input, follow-up boxes (if more than 1) that allow the input of the names (1 per box). It then needs to create the email, placing the input box data into the body text. Each email text will be based on the input from the 1st input box, so it can adjust for the number of employees (so there could be up to 5 employees on each email).
How do I assign values to my variables (findstrs and foundcells)so that they will adjust to the inputs of the inputboxes without writing all the IF stmts?
Dim aOutlook As Object
Dim aEmail As Object
Dim rngeAddresses As Range, rngeCell As Range, strRecipients As String
Dim strbox As String
Dim stritem As String
Dim X As Long
Dim r As Long
Dim LR, lookrng As Range
Dim findStr As String
Dim nameCol As Range
Dim nameCol1 As Range
Dim nameCol2 As Range
Dim nameCol3 As Range
Dim nameCol4 As Range
Dim foundCell As Variant
Dim foundCell1 As Variant
Dim foundcell2 As Variant
Dim strname As String
Dim strBody As String
Dim sigString As String
Dim signature As String
Dim findstr1 As String
Dim foundrng As Range
Dim valuefound As Boolean
Dim strFilename As String
Select Case Application.ActiveWindow.Class
Case olInspector
Set oMail = ActiveInspector.CurrentItem
Case olExplorer
Set oMail = ActiveExplorer.Selection.Item(1)
End Select
If Dir(sigString) <> "" Then
signature = GetBoiler(sigString)
Else
signature = ""
End If
Set oReply = oMail.ReplyAll
Select Case Application.ActiveWindow.Class
Case olInspector
Set oMail = ActiveInspector.CurrentItem
Case olExplorer
Set oMail = ActiveExplorer.Selection.Item(1)
End Select
Set aOutlook = CreateObject("Outlook.Application")
Set oReply = aOutlook.CreateItem(0)
'Input box(es)
findStr = InputBox("Enter Number of Employees")
findstr1 = InputBox("Enter Name of First Employee")
If findStr = "2" Then findstr2 = InputBox("Enter Name of Second Employee")
If findstr1 = "T1" Then foundCell1 = "<B>Test 1 ID#0000</B>"
If findstr1 = "T2" Then foundcell2 = "<B>Test 2 IDO#0001</B>"
If findstr1 = "T3" Then foundcell3 = "<B>Test 3 ID#0002</B>"
If findstr1 = "T4" Then foundCell4 = "<B>Test 4 ID#0003</B>"
If findstr1 = "T5" Then foundCell5 = "<B>Test 5 ID#0004</B>"
If findstr2 = "T1" Then foundCell1 = "<B>Test 1 ID#0000</B>"
If findstr2 = "T2" Then foundcell2 = "<B>Test 2 IDO#0001</B>"
If findstr2 = "T3" Then foundcell3 = "<B>Test 3 ID#0002</B>"
If findstr2 = "T4" Then foundCell4 = "<B>Test 4 ID#0003</B>"
If findstr2 = "T5" Then foundCell5 = "<B>Test 5 ID#0004</B>"
'Greeting based on time of day
Select Case Time
Case 0.25 To 0.5
GreetTime = "Good morning"
Case 0.5 To 0.71
GreetTime = "Good afternoon"
Case Else
GreetTime = "Good evening"
End Select
sigString = Environ("appdata") & _
"\Microsoft\Signatures\Update.htm"
If Dir(sigString) <> "" Then
signature = GetBoiler(sigString)
Else
signature = ""
End If
If findStr = "1" Then
strBody = "<Font Face=calibri>Can you please update the following: <br><br>" & _
"<B>" & foundCell1 & "</B><br><br>" & _
"Please update this batch. " & _
"I Appreciate your help. Let me know if you need anything.<br><br>" & _
"Thanks <br><br>" & _
subject = "Employee Update"
ElseIf findStr = "2" Then
strBody = "<Font Face=calibri>Can you please add changes for the following: " & _
"<ol><li><B>" & foundCell1 & "</B><br><br><br><br>" & _
"<li><B>" & foundcell2 & "</B><br><br>" & _
subject = "Multiple Employee Requests"
End If
'Sets up the email itself and then displays for review before sending
With oReply
.HTMLBody = "<Font Face=calibri>Hi there,<br><br>" & strBody & signature
.To = "superman#krypton.com"
.CC = "trobbins#shawshank.com "
.subject = "Multiple Employee Updates"
.Importance = 2
.Display
End With
End Sub
You need to break this code down into multiple, smaller and parameterized scopes.
Make a Function that returns the body of the email given a Collection of batch numbers.
Private Function GetEmailBody(ByVal batchNumbers As Collection) As String
Now, the calling code needs to know how many employees there are. Make a function for that.
Private Function GetNumberOfEmployees() As Long
Dim rawInput As Variant
rawInput = InputBox("Number of employees?")
If StrPtr(rawInput) = 0 Then
'user cancelled out of the prompt
GetNumberOfEmployees = -1
Exit Function
Else If IsNumeric(rawInput) Then
GetNumberOfEmployees = CLng(rawInput)
End If
End Function
That'll return -1 if user cancels the prompt, 0 for an invalid input, and the number of employees otherwise.
Dim employeeName As String
Dim nbEmployees As Long
nbEmployees = GetNumberOfEmployees
If nbEmployees = -1 Then
Exit Sub 'bail out
Else If nbEmployees = 0 Then
'reprompt?
Exit Sub 'bail out, cancelled
End If
'fun part here
Dim emailbody As String
emailBody = GetEmailBody(batchNumbers, employeeName)
And now the fun part: you need to add as many items to some batchNumbers collection, as you have nbEmployees. Because you know how many iterations you'll need before you start looping, a For loop will do.
Dim batchNumbers As Collection
Set batchNumbers = New Collection
Dim batchNumber As String
Dim i As Long
For i = 1 To nbEmployees
batchNumber = GetBatchNumber(i)
If batchNumber = vbNullString Then Exit Sub 'bail out:cancelled/invalid
batchNumbers.Add batchNumber
Next
Dim body As String
body = GetEmailBody(batchNumbers)
Where GetBatchNumber(i) is yet another function call, to a function whose role it is to prompt for an employee number and lookup & return the corresponding batch number, returning an empty string if prompt is cancelled or no match is found.
Private Function GetBatchNumber(ByVal index As Long) As String
Dim rawInput As Variant
rawInput = InputBox("Name of employe " & index & ":")
If StrPtr(rawInput) = 0 Then
'cancelled
Exit Function
Else
Dim employeeName as String
employeeName = CStr(rawInput)
GetBatchNumber = GetBatchForEmployee(employeeName)
End If
End Function
If the mappings really actually look like T1 -> <B>Test 1 ID#000</B> then you can probably use this:
Private Function GetBatchForEmployee(ByVal employeeName As String)
Dim digit As Long
digit = CLng(Right$(employeeName, 1))
GetBatchForEmployee = "<B>Test " & digit & " ID#" & Format$(digit - 1, "000") & "</B>"
End Function
If your mappings are actual mappings then you can have a Dictionary lookup in here, or look them up on an Excel worksheet, a CSV or XML data file, a SQL Server database, whatever.
But first, break things down. A procedure that starts like this:
Dim aOutlook As Object
Dim aEmail As Object
Dim rngeAddresses As Range, rngeCell As Range, strRecipients As String
Dim strbox As String
Dim stritem As String
Dim X As Long
Dim r As Long
Dim LR, lookrng As Range
Dim findStr As String
Dim nameCol As Range
Dim nameCol1 As Range
Dim nameCol2 As Range
Dim nameCol3 As Range
Dim nameCol4 As Range
Dim foundCell As Variant
Dim foundCell1 As Variant
Dim foundcell2 As Variant
Dim strname As String
Dim strBody As String
Dim sigString As String
Dim signature As String
Dim findstr1 As String
Dim foundrng As Range
Dim valuefound As Boolean
Dim strFilename As String
...is a procedure that's doing way too many things.

GetOpenFileName Multiselect:= True error when cancel is clicked

I am very new to VBA. I keep on getting an error of type mismatch whenever the cancel/quit button in the dialogue box is clicked. The error appears on the Application.GetOpenFileName line. Does anyone know what is wrong here? I have tried several methods but none of them work :(
Thanks!
Here's my code:
Private Sub cmdBrowse_Click()
Application.ScreenUpdating = False
Dim i As Long, j As Long, iCheck As Long
Dim fname() As Variant
Dim wkbNameList As String, wkbNamePath As String
Dim win As Window
fname = Application.GetOpenFilename(filefilter:="Excel, *xlsx; *xlsm", MultiSelect:=True)
If fname = "False" Then
Exit Sub
End If
For i = LBound(fname) To UBound(fname)
workbooks.Open Filename:=fname(i)
wkbNameList = wkbNameList & workbooks(i + 1).Name & vbCrLf
wkbNamePath = wkbNamePath & fname(i) & " , "
Next i
function returns an array when files are selected, but returns a string when cancel/quit is selected
try this
Private Sub cmdBrowse_Click()
Application.ScreenUpdating = False
Dim i As Long, j As Long, iCheck As Long
Dim fname As Variant
Dim wkbNameList As String, wkbNamePath As String
Dim win As Window
fname = Application.GetOpenFilename(filefilter:="Excel, *xlsx; *xlsm", MultiSelect:=True)
If IsArray(fname) Then 'file selected
For i = LBound(fname) To UBound(fname)
Workbooks.Open Filename:=fname(i)
wkbNameList = wkbNameList & Workbooks(i + 1).Name & vbCrLf
wkbNamePath = wkbNamePath & fname(i) & " , "
Next i
ElseIf fname = "False" Then 'cancel/quit
Exit Sub
End If
End Sub
As pointed out by Kostas K. in the comments on h2so4's reply, the method returns boolean (False) when the dialog is cancelled, and array when a file is chosen.
I'd suggest trying this slight modification of h2so4's code:
Private Sub cmdBrowse_Click()
Application.ScreenUpdating = False
Dim i As Long, j As Long, iCheck As Long
Dim fname() As Variant
Dim wkbNameList As String, wkbNamePath As String
Dim win As Window
fname = Application.GetOpenFilename(filefilter:="Excel, *xlsx; *xlsm", MultiSelect:=True)
'the only option to get boolean is to have cancelled the dialog, which gives False for the variable
If VarType(fname) = vbBoolean Then
Exit Sub
Else
For i = LBound(fname) To UBound(fname)
workbooks.Open Filename:=fname(i)
wkbNameList = wkbNameList & workbooks(i + 1).Name & vbCrLf
wkbNamePath = wkbNamePath & fname(i) & " , "
Next i
End If
End Sub
'I ran into this problem working with multiselect as well
'Something like this will work
'The problem is [cancel] returns a Boolean instead of an array.. so we make it return an array
Dim fname(), fname_catcherror() As Variant
fname_catcherror = Array(Application.GetOpenFilename(filefilter:="Excel, *xlsx; *xlsm", MultiSelect:=True), True)
if VarType(fname_catcherror(0)) <> vbBoolean Then
fname = fname_catcherror(0)
'..code here
end if

Delete specific lines in a text file using vb.net

I am trying to delete some specific lines of a text using VB.Net. I saw a solution here however it is in VB6. The problem is, I am not really familiar with VB6. Can somebody help me?
This is the code from the link:
Public Function DeleteLine(ByVal fName As String, ByVal LineNumber As Long) _As Boolean
'Purpose: Deletes a Line from a text file
'Parameters: fName = FullPath to File
' LineNumber = LineToDelete
'Returns: True if Successful, false otherwise
'Requires: Reference to Microsoft Scripting Runtime
'Example: DeleteLine("C:\Myfile.txt", 3)
' Deletes third line of Myfile.txt
'______________________________________________________________
Dim oFSO As New FileSystemObject
Dim oFSTR As Scripting.TextStream
Dim ret As Long
Dim lCtr As Long
Dim sTemp As String, sLine As String
Dim bLineFound As Boolean
On Error GoTo ErrorHandler
If oFSO.FileExists(fName) Then
oFSTR = oFSO.OpenTextFile(fName)
lCtr = 1
Do While Not oFSTR.AtEndOfStream
sLine = oFSTR.ReadLine
If lCtr <> LineNumber Then
sTemp = sTemp & sLine & vbCrLf
Else
bLineFound = True
End If
lCtr = lCtr + 1
Loop
oFSTR.Close()
oFSTR = oFSO.CreateTextFile(fName, True)
oFSTR.Write(sTemp)
DeleteLine = bLineFound
End If
ErrorHandler:
On Error Resume Next
oFSTR.Close()
oFSTR = Nothing
oFSO = Nothing
End Function
Dim delLine As Integer = 10
Dim lines As List(Of String) = System.IO.File.ReadAllLines("infile.txt").ToList
lines.RemoveAt(delLine - 1) ' index starts at 0
System.IO.File.WriteAllLines("outfile.txt", lines)
'This can also be the file that you read in
Dim str As String = "sdfkvjdfkjv" & vbCrLf & "dfsgkjhdfj" & vbCrLf & "dfkjbhhjsdbvcsdhjbvdhs" & vbCrLf & "dfksbvashjcvhjbc"
Dim str2() As String = str.Split(vbCrLf)
For Each s In str2
If s.Contains("YourString") Then
'add your line to txtbox
Else
'don't add your line to txtbox
End If
Next
Or You Can Use
TextFile = TextFile.Replace("You want to Delete","")