I need an 'autorun' piece of VBA for Word 2013 to either add or remove a Watermark dependent on the filename of the document. I want to add this to a template we use for our Technical Reports which, in turn, are generated by an external Application/System and automatically named in the process. So the same document template may be named differently dependent on workflow
For documents entitled "DRAFT.XXX.NNNNNNNN.." I want a 'Draft' watermark
For any other documents there should be no watermark (or the watermark could be coloured white, ie invisible)
I've successfully created VBA/Macros to insert or remove Watermarks:
Sub InsertWaterMark()
Dim strWMName As String
On Error GoTo ErrHandler
'selects all the sheets
ActiveDocument.Sections(1).Range.Select
strWMName = ActiveDocument.Sections(1).Index
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
'Change the text for your watermark here
Selection.HeaderFooter.Shapes.AddTextEffect(msoTextEffect1, _
"DRAFT", "Arial", 1, False, False, 0, 0).Select
With Selection.ShapeRange
.Name = strWMName
.TextEffect.NormalizedHeight = False
.Line.Visible = False
With .Fill
.Visible = True
.Solid
.ForeColor.RGB = Gray
.Transparency = 0.5
End With
.Rotation = 315
.LockAspectRatio = True
.Height = InchesToPoints(2.42)
.Width = InchesToPoints(6.04)
With .WrapFormat
.AllowOverlap = True
.Side = wdWrapNone
.Type = 3
End With
.RelativeHorizontalPosition = wdRelativeVerticalPositionMargin
.RelativeVerticalPosition = wdRelativeVerticalPositionMargin
'If using Word 2000 you may need to comment the 2
'lines above and uncomment the 2 below.
' .RelativeHorizontalPosition = wdRelativeVerticalPositionPage
' .RelativeVerticalPosition = wdRelativeVerticalPositionPage
.Left = wdShapeCenter
.Top = wdShapeCenter
End With
ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
Selection.Collapse Direction:=wdCollapseEnd
Exit Sub
ErrHandler:
MsgBox "An error occured trying to insert the watermark." & Chr(13) & _
"Error Number: " & Err.Number & Chr(13) & _
"Decription: " & Err.Description, vbOKOnly + vbCritical, "Error"
End Sub
Sub RemoveWaterMark()
Dim strWMName As String
On Error GoTo ErrHandler
ActiveDocument.Sections(1).Range.Select
strWMName = ActiveDocument.Sections(1).Index
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
Selection.HeaderFooter.Shapes(strWMName).Select
Selection.Delete
ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
Selection.Collapse Direction:=wdCollapseEnd
Exit Sub
ErrHandler:
'MsgBox "An error occured trying to remove the watermark." & Chr(13) & _
'"Error Number: " & Err.Number & Chr(13) & _
'"Decription: " & Err.Description, vbOKOnly + vbCritical, "Error"
ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
Selection.Collapse Direction:=wdCollapseEnd
End Sub
I've created an AutoOpen macro which checks the first five characters of the document for "DRAFT", "Draft" or "draft" and then it should call the appropriate Subroutine:
Sub AutoOpen()
Dim oldfilename As String
Dim draft As String
oldfilename = ActiveDocument.Name
draft = Left(oldfilename, 5)
Select Case draft
Case "DRAFT", "Draft", "draft"
Call InsertWaterMark
Case Else
Call RemoveWaterMark
End Select
Exit Sub
BUT I'm getting an error when the code branches to the InsertWatermark Subroutine and the line
.Name = strWMName
I then get an error:
An error occurred trying to insert the watermark. Error Number: 70 Description: Permission denied
How can I fix the error?
You need to convert Integer which comes from .Sections(1).Index property into string. Two suggestions:
.Name = Cstr(strWMName)
or
.Name = "WaterMarkName" & strWMName
Please remember to change accordingly in RemoveWaterMark subroutine.
Related
Need little help from this forum.
I want to replace shape(autoshape) with other autoshape in my project & found a solution here http://www.vbaexpress.com/forum/showthread.php?68760-Change-Fill-color-using-VBA-in-PowerPoint.
But in my project there are some shapes which contains text(I did not use textbox).
The code are select shape(which will be replaced) by some critaria
ie
by height 2. by weidth 3. fill colour 4. by top position.
As textbox is not a autoshape thats why I used shape which contains text & to give text backgroung transparent I used 'shape fill' to 'no fill'.
In my project there are shapes(not contains text) which are same size & same top position(ie the shape just behind the text shape).
Code is working fine for those shape which did not contains text.When I select the text shape & run the code it replaced all the shape behind the text shape ie
not replace the text shape(which I want to replace).
I tried a lot but not getting the solution.I also tried with changeing the weidth of the shape behind the textshape but not get desire result.
Sir any solution will be highly appreaciate.
Option Explicit
Dim oShapeAfterChange As Shape, oShapeToChange As Shape
Dim tShapeAfterChange As MsoAutoShapeType, tShapeToChange As MsoAutoShapeType
Dim iShapeAfterChangeRGB As Long, iShapeAfterChangeHeight As Double, iShapeAfterChangeWidth As Double, iShapeAfterChangeTop As Double
Sub Step1()
If MsgBox("This is Step 1 of a two step process" & vbCrLf & vbCrLf & _
"1. You must already have inserted and selected a new Shape to change to" & vbCrLf & _
"2. After running, Step1 will remember the new type of shape" & vbCrLf & _
"3. Select one of the shapes to be changed" & vbCrLf & _
"4. Run the Step2 Macro", vbOKCancel + vbInformation, "Change Shapes") = vbCancel Then
Exit Sub
End If
Set oShapeAfterChange = Nothing
On Error Resume Next
Set oShapeAfterChange = ActiveWindow.Selection.ShapeRange(1)
oShapeAfterChange.PickUp
tShapeAfterChange = oShapeAfterChange.AutoShapeType
On Error GoTo 0
If oShapeAfterChange Is Nothing Then
Call MsgBox("You must select an AutoShape", vbCritical + vbOKOnly, "Change Shapes")
Exit Sub
End If
Call MsgBox("Destination Shape type memorized", vbOK + vbInformation, "Change Shapes")
End Sub
Sub Step2()
Dim oPres As Presentation
Dim oSlide As Slide
Dim oShape As Shape, oShapeInGroup As Shape
If MsgBox("This is Step 2 of a two step process" & vbCrLf & vbCrLf & _
"1. You must already have selected an instance of a Shape to change" & vbCrLf & _
"2. All instances on all slides of that type of Shape will be changed", vbOKCancel + vbInformation, "Change Shapes") = vbCancel Then
Exit Sub
End If
If oShapeAfterChange Is Nothing Then
Call MsgBox("1. You must select an example of a new Shape to change the shapes to" & vbCrLf & _
"2. Re-run Step1", vbCritical + vbOKOnly, "Change Shapes")
Exit Sub
End If
Set oShapeToChange = Nothing
Set oShapeToChange = ActiveWindow.Selection.ShapeRange(1)
If oShapeToChange.Type = msoGroup Then
If ActiveWindow.Selection.HasChildShapeRange Then
If ActiveWindow.Selection.ChildShapeRange.Count <> 1 Then
Call MsgBox("You must select exactly one Shape within the Group of the type to be changed", vbCritical + vbOKOnly, "Change Shapes")
Exit Sub
Else
Set oShapeToChange = ActiveWindow.Selection.ChildShapeRange(1)
End If
End If
End If
If oShapeToChange Is Nothing Then
Call MsgBox("You must select a Shape of the type to be changed", vbCritical + vbOKOnly, "Change Shapes")
Exit Sub
End If
With oShapeToChange
tShapeToChange = .AutoShapeType
iShapeAfterChangeRGB = .Fill.ForeColor.RGB
iShapeAfterChangeHeight = Round(.Height, 0)
iShapeAfterChangeWidth = Round(.Width, 0)
iShapeAfterChangeTop = Round(.Top, 0)
End With
Set oPres = ActivePresentation
For Each oSlide In oPres.Slides
For Each oShape In oSlide.Shapes
If oShape.Type = msoGroup Then
For Each oShapeInGroup In oShape.GroupItems
Call pvtChangeAutoShapeType(oShapeInGroup)
Next
Else
Call pvtChangeAutoShapeType(oShape)
End If
Next
Next
oShapeAfterChange.Delete
MsgBox "Shapes updated successfully"
End Sub
Private Sub pvtChangeAutoShapeType(o As Shape)
Dim CenterTop As Double, CenterLeft As Double
With o
If .Type <> msoAutoShape Then Exit Sub
If .AutoShapeType <> tShapeToChange Then Exit Sub
If .Fill.ForeColor.RGB <> iShapeAfterChangeRGB Then Exit Sub
If Round(.Height, 0) <> iShapeAfterChangeHeight Then Exit Sub
If Round(.Width, 0) <> iShapeAfterChangeWidth Then Exit Sub
If Round(.Top, 0) <> iShapeAfterChangeTop Then Exit Sub
.AutoShapeType = tShapeAfterChange
CenterTop = .Top + .Height / 2#
CenterLeft = .Left + .Width / 2#
.Height = oShapeAfterChange.Height
.Width = oShapeAfterChange.Width
.Left = CenterLeft - oShapeAfterChange.Width / 2#
.Top = CenterTop - oShapeAfterChange.Height / 2#
.Apply
End With
End Sub
I have a userform that allows users to insert an intentionally blank page after the cover page if they need to print the document. I can get this to work just fine when i only need to insert 1 or 2 blank pages throughout the document, however I now have a new document where i need to insert a total of 14 blank pages if the userform combobox is changed to "Printable Format"
The code i use for the current document is below as reference but I think for adding so many blank pages i'm better to use a loop or find instead of this.
All of my bookmarks for where blank pages are to be added are named "Print" with sequential numbers (ie. "Print 1", Print2" etc) so i was hoping to be able to search through the document for all bookmarks containing the name "Print" but i can't seem to figure it out!
Dim answer As Integer
Dim BMBreak As Range
Dim BMBreak2 As Range
With ActiveDocument
'Insert bookmarks applicable to Printable Format
If CbxPrint.Value = "Printable Format" Then
answer = MsgBox("You have changed the document to Printable Format." & vbNewLine _
& "This will add intentionally blank pages throughout the document " & vbNewLine _
& "Do you wish to continue?", vbOKCancel, "WARNING")
If answer = vbOK Then
'Intentional blank page after title page
Set BMRange = ActiveDocument.Bookmarks("Print1").Range
BMRange.Collapse wdCollapseStart
BMRange.InsertBreak wdPageBreak
BMRange.Text = "THIS PAGE IS INTENTIONALLY BLANK"
BMRange.ParagraphFormat.SpaceBefore = 36
BMRange.ParagraphFormat.Alignment = wdAlignParagraphCenter
ActiveDocument.Bookmarks.Add "Print1", BMRange
With BMRange
.Collapse Direction:=wdCollapseEnd
.InsertBreak Type:=wdSectionBreakContinuous
End With
With ActiveDocument.Sections(3)
.Headers(wdHeaderFooterPrimary).LinkToPrevious = False
.Footers(wdHeaderFooterPrimary).LinkToPrevious = False
End With
With ActiveDocument.Sections(2)
.Headers(wdHeaderFooterPrimary).LinkToPrevious = False
.Headers(wdHeaderFooterPrimary).Range.Delete
.Footers(wdHeaderFooterPrimary).LinkToPrevious = False
.Footers(wdHeaderFooterPrimary).Range.Delete
End With ```
Code like the following will process any number of Print# bookmarks (presently limited to 20, which need not all exist):
Dim i As Long, BMRange As Range
With ActiveDocument
If CbxPrint.Value = "Printable Format" Then
If MsgBox("You have changed the document to Printable Format." & vbCr & _
"This will add intentionally blank pages throughout the document " & vbCr _
& "Do you wish to continue?", vbOKCancel, "WARNING") = vbOK Then
'Process bookmarks applicable to Printable Format
For i = 20 To 1 Step -1
If .Bookmarks.Exists("Print" & i) = True Then
'Intentional blank page
Set BMRange = .Bookmarks("Print" & i).Range
With BMRange
.Collapse wdCollapseEnd
.InsertBreak Type:=wdSectionBreakNextPage
.InsertBreak Type:=wdSectionBreakNextPage
.Start = .Start - 1
.Sections.Last.Headers(wdHeaderFooterPrimary).LinkToPrevious = False
.Sections.Last.Footers(wdHeaderFooterPrimary).LinkToPrevious = False
With .Sections.First
.Headers(wdHeaderFooterPrimary).LinkToPrevious = False
.Footers(wdHeaderFooterPrimary).LinkToPrevious = False
.Headers(wdHeaderFooterPrimary).Range.Delete
.Footers(wdHeaderFooterPrimary).Range.Delete
.Range.InsertBefore "THIS PAGE IS INTENTIONALLY BLANK"
.Range.ParagraphFormat.SpaceBefore = 36
.Range.ParagraphFormat.Alignment = wdAlignParagraphCenter
End With
.Start = .Start - 1
.Bookmarks.Add "Print" & i, .Duplicate
End With
End If
Next
End If
End If
End With
I have a excel file and there are 20 sheets
I need to search and find several sheet on my excel that want and add email to M1 Cell
Could you please help me.
Application.ScreenUpdating = False
On Error Resume Next
Application.DisplayAlerts = False
döngü:
For i = 1 To Worksheets.Count
If Worksheets(i).Name = "ABC" Then
Sheets("ABC").Select
Range("M1").Select
ActiveCell.FormulaR1C1 = "abc#hotmail.com"
If Worksheets(i).Name = "ABC2" Then
Sheets("ABC2").Select
Range("M1").Select
ActiveCell.FormulaR1C1 = "abc2#hotmail.com"
GoTo döngü:
pass:
Next i
Application.ScreenUpdating = True
MsgBox "mail assign done"
End Sub
You can simply use below sub.
Sub WriteEmail()
On Error GoTo HarunErrHandler
Sheets("ABC").Range("M1") = "abc#hotmail.com"
Sheets("ABC2").Range("M1") = "abc2#hotmail.com"
Exit Sub
HarunErrHandler:
MsgBox "No such sheet found.", vbInformation, "Info"
'MsgBox("Error Number: " & Err.Number & vbCrLf & Err.Description, vbCritical, "Error")
End Sub
Many thanks Harun i made a little change with your comments.
Following code worked well.
Thank you so much
Sub WriteEmail()
Sheets("ABC").Range("M1") = "abc#hotmail.com"
On Error Resume Next
Sheets("ABC2").Range("M1") = "abc2#hotmail.com"
On Error Resume Next
Sheets("ABC3").Range("M1") = "abc3#hotmail.com"
On Error Resume Next
MsgBox ("process done")
End Sub
I am having an issue regarding VBA in Word 2013. I have limited experience with coding, and macros are a bit of new territory for me.
I have a successful VBA code from a worker that no longer works in my office, and this code allows for a drop down menu in the office forms, allowing the user to choose their location and the footer changes the text address of the office in a string.
What I have been trying to do is to tweak this code so that on choosing the location, instead of showing text at the bottom of the page, the header template will change. I have successfully recorded the macros so it will do what I want on my computer, but when I try to share it with others, a few things happen. The drop down menu doesn't appear, then I have to put in the Developer tab. After that I have to unlock the document each time I want to run the macro (the old documents did not require this even though the old documents are also locked), then I get the error code saying the requested member does not exist, pointing to my recorded macro.
I'm sure I am doing something wrong but I'm unsure what that is. Some help would be greatly appreciated.
Option Explicit
Sub AutoNew()
Dim Mybar As CommandBar
Dim myControl As CommandBarComboBox
Dim cmd As CommandBar
Dim cmdyes As Integer
cmdyes = 0
For Each cmd In CommandBars
If cmd.Name = "Select Location" Then
cmdyes = 1
Exit For
Else
End If
Next
If cmdyes = 1 Then
CommandBars("Select Location").Visible = True
Else
Set Mybar = CommandBars _
.Add(Name:="Select Location", Position:=msoBarFloating, _
Temporary:=False)
Set myControl = CommandBars("Select Location").Controls _
.Add(Type:=msoControlDropdown, Before:=1)
With myControl
.AddItem " South Portland"
.AddItem " Bangor"
.AddItem " Presque Isle"
.ListIndex = 1
.Caption = "Select Office Location"
.Style = msoComboLabel
.BeginGroup = True
.OnAction = "processSelection"
.Tag = "AddresSelect"
End With
End If
CommandBars("Select Location").Visible = True
If ActiveDocument.ProtectionType = wdAllowOnlyFormFields = False Then
ActiveDocument.Protect Type:=wdAllowOnlyFormFields, NoReset:=True,
Password:="password"
' ActiveDocument.Protect Type:=wdAllowOnlyFormFields, NoReset:=True,
Password:=""
End If
End Sub
Sub AutoOpen()
Dim Mybar As CommandBar
Dim myControl As CommandBarComboBox
Dim cmd As CommandBar
Dim cmdyes As Integer
cmdyes = 0
For Each cmd In CommandBars
If cmd.Name = "Select Location" Then
cmdyes = 1
Exit For
Else
End If
Next
If cmdyes = 1 Then
CommandBars("Select Location").Visible = True
Else
Set Mybar = CommandBars _
.Add(Name:="Select Location", Position:=msoBarFloating, _
Temporary:=False)
Set myControl = CommandBars("Select Location").Controls _
.Add(Type:=msoControlDropdown, Before:=1)
With myControl
.AddItem " South Portland"
.AddItem " Bangor"
.AddItem " Presque Isle"
.ListIndex = 1
.Caption = "Select Office Location"
.Style = msoComboLabel
.BeginGroup = True
.OnAction = "processSelection"
.Tag = "AddresSelect"
End With
End If
CommandBars("Select Location").Visible = True
If ActiveDocument.ProtectionType = wdAllowOnlyFormFields = False Then
ActiveDocument.Protect Type:=wdAllowOnlyFormFields, NoReset:=True,
Password:="password"
' ActiveDocument.Protect Type:=wdAllowOnlyFormFields, NoReset:=True,
Password:=""
End If
End Sub
Sub processSelection()
Dim userChoice As Long
userChoice = CommandBars("Select Location").Controls(1).ListIndex
Select Case userChoice
Case 1
Call SoPortlandAddress
Case 2
Call BangorAddress
Case Else
Call PresqueIsleAddress
End Select
End Sub
Sub SoPortlandAddress()
'
' SoPortlandAddress Macro
'
'
If ActiveWindow.View.SplitSpecial <> wdPaneNone Then
ActiveWindow.Panes(2).Close
End If
If ActiveWindow.ActivePane.View.Type = wdNormalView Or ActiveWindow. _
ActivePane.View.Type = wdOutlineView Then
ActiveWindow.ActivePane.View.Type = wdPrintView
End If
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
Templates.LoadBuildingBlocks
Application.Templates( _
"C:\Users\bex172\AppData\Roaming\Microsoft\Document Building
Blocks\1033\15\Building Blocks.dotx" _
).BuildingBlockEntries("South Portland Header").Insert Where:=Selection.
_
Range, RichText:=True
ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
If ActiveDocument.ProtectionType = wdAllowOnlyFormFields Then
ActiveDocument.Unprotect Password:="password"
End If
If ActiveDocument.ProtectionType = wdNoProtection Then
FormLock
End If
End Sub
Sub BangorAddress()
'
' BangorAddress Macro
'
'
If ActiveWindow.View.SplitSpecial <> wdPaneNone Then
ActiveWindow.Panes(2).Close
End If
If ActiveWindow.ActivePane.View.Type = wdNormalView Or ActiveWindow. _
ActivePane.View.Type = wdOutlineView Then
ActiveWindow.ActivePane.View.Type = wdPrintView
End If
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
Templates.LoadBuildingBlocks
Application.Templates( _
"C:\Users\bex172\AppData\Roaming\Microsoft\Document Building
Blocks\1033\15\Building Blocks.dotx" _
).BuildingBlockEntries("Bangor Header").Insert Where:=Selection.Range, _
RichText:=True
ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
If ActiveDocument.ProtectionType = wdAllowOnlyFormFields Then
ActiveDocument.Unprotect Password:="password"
End If
If ActiveDocument.ProtectionType = wdNoProtection Then
FormLock
End If
End Sub
Sub PresqueIsleAddress()
'
' PresqueIsleAddress Macro
'
'
If ActiveWindow.View.SplitSpecial <> wdPaneNone Then
ActiveWindow.Panes(2).Close
End If
If ActiveWindow.ActivePane.View.Type = wdNormalView Or ActiveWindow. _
ActivePane.View.Type = wdOutlineView Then
ActiveWindow.ActivePane.View.Type = wdPrintView
End If
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
Templates.LoadBuildingBlocks
Application.Templates( _
"C:\Users\bex172\AppData\Roaming\Microsoft\Document Building
Blocks\1033\15\Building Blocks.dotx" _
).BuildingBlockEntries("Presque Isle Header").Insert Where:=Selection. _
Range, RichText:=True
ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
If ActiveDocument.ProtectionType = wdAllowOnlyFormFields Then
ActiveDocument.Unprotect Password:="password"
End If
If ActiveDocument.ProtectionType = wdNoProtection Then
FormLock
End If
End Sub
Sub FormLock()
'
' ToggleFormLock Macro
' Macro created 1/27/2004 by name removed
'
If ActiveDocument.ProtectionType = wdAllowOnlyFormFields = False Then
ActiveDocument.Protect Type:=wdAllowOnlyFormFields, NoReset:=True,
Password:="password"
'if a password is used, add the line below after a space above
'Password:="myPassword"
Else
'if a password is used, add a comma after
'the last line and include the line below
'Password:="myPassword"
End If
End Sub
I found your code a little unwieldy and understand that it poses a problem for you. The abbreviated version below should be easier to understand and therefore easier for you to manage once you acquaint yourself with its own peculiarities. Note that I tested everything except the actual extraction and insertion of the building block, since you said it is working.
Option Explicit
' declare the name (so as to eliminate typos)
Const CmdName As String = "Select Location"
Sub AutoNew()
' 12 Oct 2017
SetCommandBar
End Sub
Sub AutoOpen()
' 12 Oct 2017
SetCommandBar
End Sub
Sub SetCommandBar()
' 12 Oct 2017
Dim MyBar As CommandBar
Dim MyCtl As CommandBarControl
Dim MyList() As String
Dim Cmd As CommandBar
Dim i As Integer
' delete the existing (so that you can modify it)
For Each Cmd In CommandBars
If Cmd.Name = CmdName Then
Cmd.Delete
Exit For
End If
Next Cmd
' in Word >= 2007 the commandbar will be displayed
' in the ribbon's Add-ins tab
Set MyBar = CommandBars.Add(Name:=CmdName, _
Position:=msoBarFloating, _
MenuBar:=True, _
Temporary:=True)
Set MyCtl = CommandBars(CmdName).Controls.Add( _
Type:=msoControlDropdown, _
Before:=1)
' Names must match Building Block names (without " Header")
MyList = Split(" South Portland, Bangor, Presque Isle", ",")
With MyCtl
.Caption = "Select Office Location"
.Style = msoComboLabel
For i = 0 To UBound(MyList)
.AddItem MyList(i)
Next i
.ListIndex = 1
.OnAction = "SetHeader"
End With
CommandBars(CmdName).Visible = True
End Sub
Sub SetHeader()
' 12 Oct 2017
Const BlockFile As String = "C:\Users\bex172\AppData\Roaming\Microsoft\" & _
"Document Building Blocks\1033\15\" & _
"Building Blocks.dotx"
Dim BlockID As String
SetFormLock False ' not needed if the document isn't locked
With ActiveWindow
If .View.SplitSpecial <> wdPaneNone Then .Panes(2).Close
With .ActivePane.View
If .Type = wdNormalView Or .Type = wdOutlineView Then
.Type = wdPrintView
End If
.SeekView = wdSeekCurrentPageHeader
End With
End With
BlockID = Trim(CommandBars(CmdName).Controls(1).Text) & " Header"
Templates.LoadBuildingBlocks
Application.Templates(BlockFile).BuildingBlockEntries(BlockID).Insert _
Where:=Selection.Range, _
RichText:=True
SetFormLock True ' not needed if the document isn't to be locked
End Sub
Sub SetFormLock(ByVal FormLock As Boolean)
' 12 Oct 2017
' call this procedure with either "True" or "False" as argument
' to either lock or unlock the form.
' The same password is used for unlocking and locking.
' MAKE SURE THE DOCUMENT IS UNLOCKED before changing the password!
Const Password As String = ""
Dim Doc As Document
Set Doc = ActiveDocument
With Doc
If .ProtectionType = wdNoProtection Then
If FormLock Then
' you can't set the protection while any other part of the document is active
ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
' you may wish to specify another type of protection:
' this code protects all except FormFields
.Protect Type:=WdProtectionType.wdAllowOnlyFormFields, _
NoReset:=True, _
Password:=Password, _
UseIRM:=False, _
EnforceStyleLock:=False
End If
Else
If Not FormLock Then .Unprotect Password
End If
End With
End Sub
Your question didn't allow full understanding of your problem. It might have to do with the location of the code itself or with the protection. By making the code more transparent I hope that you will either be able to eliminate the problem or find the right question to ask.
I am exporting an excel table into word using VBA. The word document has one bookmark. The code is such that first it writes the TYPE as the heading and then write all the description under that TYPE. I want the headings to be bold and formatted. I have the following code but it does not work. If anyone could suggest something.
If Dir(strPath & "\" & strFileName) <> "" Then
'Word Document open
On Error Resume Next
Set objWDApp = GetObject(, "Word.Application")
If objWDApp Is Nothing Then Set objWDApp = CreateObject("Word.Application")
With objWDApp
.Visible = True 'Or True, if Word is to be indicated
.Documents.Open (strPath & "\" & strFileName)
Set objRng = objWDApp.ActiveDocument.Bookmarks("Bookmark").Range
.Styles.Add ("Heading")
.Styles.Add ("Text")
With .Styles("Heading").Font
.Name = "Arial"
.Size = 12
.Bold = True
.Underline = True
End With
With .Styles("Text").Font
.Name = "Arial"
.Size = 10
.Bold = False
.Underline = False
End With
End With
On Error GoTo 0
i = Start_Cell
idx(1) = i
n = 2
Do ' Search for first empty cell in the table
i = i + 1
If i > Start_Cell + 1 And Cells(i, QB_Type).Value = Cells(i - 1, QB_Type) Then GoTo Loop1
idx(n) = i
n = n + 1
Loop1:
Loop Until IsEmpty(Cells(i + 1, QB_Type).Value)
idxEnd = i
idx(n) = 9999
i = Start_Cell
n = 1
Do
If i = idx(n) Then
strTMP = vbNewLine & vbNewLine & Cells(idx(n), QB_Type).Value & vbNewLine
With objWDApp
'.Selection.Font.Bold = True 'Type Bold (Doesnt Functions!?)
.Selection.Styles ("Heading") 'I tried this as well but not functioning...gives an error here that object does not support this property
WriteToWord objRng, strTMP 'Text written
End With
n = n + 1
End If
strTMP = vbNewLine & Cells(i, QB_Description).Value & vbNewLine
With objWDApp
' .Selection.Font.Bold = False 'Description Not bold (Not functioning!?)
.Selection.Styles("Text") 'This is also not functioning
WriteToWord objRng, strTMP 'Text written
End With
i = i + 1 'Arbeitspunktzähler erhöhen
Loop Until i > idxEnd
Public Sub WriteToWord(objRng, text)
With objRng
.InsertAfter text
End With
End Sub
Try .Selection.Style.Name = "Heading" from here
Edit 2
The following code works as expected. You will need to modify it to fit your needs. I successfully added and then bolded text to an existing word document.
Option Explicit
Public Sub Test()
' Add a reference to Microsoft Word x.0 Object Library for early binding and syntax support
Dim w As Word.Application
If (w Is Nothing) Then Set w = New Word.Application
Dim item As Word.Document, doc As Word.Document
' If the document is already open, just get a reference to it
For Each item In w.Documents
If (item.FullName = "C:\Path\To\Test.docx") Then
Set doc = item
Exit For
End If
Next
' Else, open the document
If (doc Is Nothing) Then Set doc = w.Documents.Open("C:\Path\To\Test.docx")
' Force change Word's default read-only/protected view
doc.ActiveWindow.View = wdNormalView
' Delete the preexisting style to avoid an error of duplicate entry next time this is run
' Could also check if the style exists by iterating through all styles. Whichever method works for you
doc.Styles.item("MyStyle").Delete
doc.Styles.Add "MyStyle"
With doc.Styles("MyStyle").Font
.Name = "Arial"
.Size = 12
.Bold = True
.Underline = wdUnderlineSingle
End With
' Do your logic to put text where you need it
doc.Range.InsertAfter "This is another Heading"
' Now find that same text you just added to the document, and bold it.
With doc.Content.Find
.Text = "This is another Heading"
.Execute
If (.Found) Then .Parent.Bold = True
End With
' Make sure to dispose of the objects. This can cause issues when the macro gets out mid way, causing a file lock on the document
doc.Close
Set doc = Nothing
w.Quit
Set w = Nothing
End Sub
By adding a reference to the object library, you can get intellisense support and compilation errors. It would help you determine earlier in development that Styles is not a valid property off the Word.Application object.