Doorgaan naar hoofdcontent

Word: Aanpassen van het lint in Word 2010 via XML en VBA

1.1     Inleiding

In de volgende voorbeelden gebruiken we de Office Custom UI Editor en Word template add-ins. We gebruiken deze manier omdat:

§   de Custom UI Editor automatisch de vereiste Open Office XML bestandsrelaties maakt
§   we dan geen additionele ontwikkelsoftware als Visual Studio nodig hebben
§   en we gewoon gebruik kunnen maken van VBA om het lint aan te roepen

De Office Custom UI Editor kunne we gratis downloaden via OpenXMLDeveloper.org: Custom UI Editor

Het aanpassen van de linten van Word zoals hier getoond, kunnen we toepassen op een los Word sjabloon of via een Word add-in.

1.2     Voorbeeld 1

Het eerste voorbeeld is tamelijk simpel. We gaan hier een losse knop op een tab verbergen. We gaan de knop Macros op de tab Beeld verbergen.

§   Maak een leeg sjabloon dat macros kan bevatten: voorbeeld1.dotm
§   Sluit het document en sluit Word.
§   Start de Office Custom UI Editor.
§   Open het sjabloon voorbeeld1.dotm.
§   Voeg de juiste Office Custom UI Part toe.


§   Plak het volgende RibbonXML script in het CustomUI venster.

  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
    <ribbon>
         <tabs>
         <tab idMso="TabView">
           <group idMso="GroupMacros" visible="false" />
         </tab>
         </tabs>
    </ribbon>
  </customUI>

§   Sla het bestand op.
§   Sluit het Custom UI Editor bestand.

Als we Voorbeeld1.dotm nu openen, zullen we zien dat de knop Macros op de tab Beeld verdwenen is.

1.3     Voorbeeld 2

We gaan nu op de tab Start knoppen toevoegen, verwijderen en herschikken. Op de tab Start zien we een groep Klembord vooraan en achteraan een groep bewerken. Die twee gaan we combineren in een nieuwe groep Bewerken en Klembord.

§   Maak een leeg sjabloon dat macros kan bevatten: voorbeeld2.dotm
§   Sluit het document en sluit Word.
§   Start de Office Custom UI Editor.
§   Open het sjabloon voorbeeld2.dotm.
§   Voeg de juiste Office Custom UI Part toe.
§   Plak het volgende RibbonXML script in het CustomUI venster.

  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
    <ribbon>
         <tabs>
         <tab idMso="TabHome">
           <group idMso="GroupEditing" visible="false" />
           <group idMso="GroupClipboard" visible="false" />
           <group id="CustomGroup" label="Bewerken en Klembord" insertBeforeMso="GroupFont">
              <splitButton idMso="PasteMenu" size="large" />
                <button idMso="Cut" />
                <button idMso="Copy" />
                  <control idMso="FormatPainter" />
                  <separator id="Sep1" />
                  <button idMso="FindDialog" />
                  <button idMso="ReplaceDialog" />
                  <menu idMso="SelectMenu" />
              <dialogBoxLauncher >
                <button idMso="ShowClipboard" />
              </dialogBoxLauncher>
           </group>
         </tab>
         </tabs>
    </ribbon>
  </customUI>

§   Sla het bestand op.
§   Sluit het Custom UI Editor bestand.

Als we Voorbeeld2.dotm nu openen, zullen we zien dat de knoppen de tab Start zijn samengevoegd.

1.4     Voorbeeld 3

In het laatste voorbeeld laten we zien hoe we eigen knoppen kunnen maken en deze toevoegen aan een eigen tab.

§   Maak een leeg sjabloon dat macros kan bevatten: voorbeeld3.dotm
§   Sluit het document en sluit Word.
§   Start de Office Custom UI Editor.
§   Open het sjabloon voorbeeld3.dotm.
§   Voeg de juiste Office Custom UI Part toe.
§   Plak het volgende RibbonXML script in het CustomUI venster.
  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="RibbonControl.Onload">
    <ribbon>
         <tabs>
         <tab id="CustomTab1" label="My Tab">
           <group id="CustGrp1" label="Macros" >
              <button id="Btn1" label="Show Visual Basic Editor" imageMso="VisualBasic"
                    onAction="RibbonControl.MyBtnMacro" />
            <dropDown id="DD1" label="Run Macro"
                      getItemCount="RibbonControl.GetItemCount"
                      getItemLabel="RibbonControl.GetItemLabel"
                      getSelectedItemIndex="RibbonControl.GetSelectedItemIndex"
                      onAction="RibbonControl.MyDDMacro" />
        </group>
        <group id="CustGrp2" label="Shortcuts" >
          <toggleButton id="TB1" size="normal"
                        getImage="RibbonControl.getImage"
                        getLabel="RibbonControl.getLabel"
                        onAction="RibbonControl.ToggleonAction"
                        getPressed="RibbonControl.buttonPressed" />
          <toggleButton id="TB2" size="normal"
                        getImage="RibbonControl.getImage"
                        getLabel="RibbonControl.getLabel"
                        onAction="RibbonControl.ToggleonAction"
                        getPressed="RibbonControl.buttonPressed" />
        </group>
      </tab>
    </tabs>
  </ribbon>
</customUI>

§   Sla het bestand op.
§   Sluit het Custom UI Editor bestand.

Nu gaan we naar het tweede deel van de oplossing: het VBA project.

§   Open voorbeeld3.dotm
§   Open de VB Editor (ALT+F11).
§   Voeg twee standaard projectmodules toe.
§   Noem deze RibbenControl en Macros.
§   Plak de volgende code in RibbonControl.

Option Explicit
Public myRibbon As IRibbonUI

Sub Onload(ribbon As IRibbonUI)
  'Creates a ribbon instance for use in this project
  Set myRibbon = ribbon
End Sub

'Callback for DropDown GetItemCount
Sub GetItemCount(ByVal control As IRibbonControl, ByRef count)
  'Tell the ribbon to show 4 items in the dropdown
  count = 4
End Sub

'Callback for DropDown GetItemLabel
Sub GetItemLabel(ByVal control As IRibbonControl, Index As Integer, ByRef label)
  'This procedure fires once for each item in the dropdown. Index is _
   received as 0, 1, 2, etc. and label is returned.
  label = Choose(Index + 1, "Select from list", "Macro 1", "Macro 2", "Macro 3")
End Sub

'Callback DropDown GetSelectedIndex
Sub GetSelectedItemIndex(ByVal control As IRibbonControl, ByRef Index)
  'This procedure is used to ensure the first item in the dropdown is selected _
   when the control is displayed
  Select Case control.id
    Case Is = "DD1"
      Index = 0
    Case Else
      'Do nothing
  End Select
End Sub

'Callback for DropDown onAction
Sub myDDMacro(ByVal control As IRibbonControl, selectedID As String, selectedIndex As Integer)
  Select Case selectedIndex
    Case 0
      'Do nothing
    Case 1
      Macros.Macro1
    Case 2
      Macros.Macro2
    Case 3
      Macros.Macro3
  End Select
  'Force the ribbon to restore the control to its original state
  myRibbon.InvalidateControl control.id
End Sub

'Callback for Button onAction
Sub MyBtnMacro(ByVal control As IRibbonControl)
  Select Case control.id
    Case Is = "Btn1"
      Macros.ShowEditor
    Case Else
      'Do nothing
  End Select
End Sub

'Callback for Toogle onAction
Sub ToggleonAction(control As IRibbonControl, pressed As Boolean)
  Select Case control.id
    Case Is = "TB1"
      ActiveWindow.View.ShowBookmarks = Not ActiveWindow.View.ShowBookmarks
    Case Is = "TB2"
      'Note: "pressed" represents the toggle state. So we could use this instead.
      If pressed Then
        ActiveWindow.View.ShowHiddenText = False
      Else
        ActiveWindow.View.ShowHiddenText = True
      End If
      If Not ActiveWindow.View.ShowHiddenText Then
        ActiveWindow.View.ShowAll = False
      End If
  End Select
  'Force the ribbon to redefine the control wiht correct image and label
  myRibbon.InvalidateControl control.id
End Sub

'Callback for togglebutton getLabel
Sub getLabel(control As IRibbonControl, ByRef returnedVal)
  Select Case control.id
    Case Is = "TB1"
      If Not ActiveWindow.View.ShowBookmarks Then
        returnedVal = "Show Bookmarks"
      Else
        returnedVal = "Hide Bookmarks"
      End If
    Case Is = "TB2"
      If Not ActiveWindow.View.ShowHiddenText Then
        returnedVal = "Show Text"
      Else
       returnedVal = "Hide Text"
      End If
  End Select
End Sub

'Callback for togglebutton getImage
Sub GetImage(control As IRibbonControl, ByRef returnedVal)
  Select Case control.id
    Case Is = "TB1"
      If ActiveWindow.View.ShowBookmarks Then
        returnedVal = "_3DTiltRightClassic" 'The idMso of a built-in control
      Else
        returnedVal = "_3DTiltLeftClassic" 'The idMso of a built-in control
      End If
    Case Is = "TB2"
      If ActiveWindow.View.ShowHiddenText Then
        returnedVal = "WebControlHidden" 'The idMso of a built-in control
      Else
        returnedVal = "SlideShowInAWindow" 'The idMso of a built-in control
     End If
  End Select
End Sub

'Callback for togglebutton getPressed
Sub buttonPressed(control As IRibbonControl, ByRef toggleState)
  'toggleState (i.e., true or false) determines how the 'toggle appears _
   on the ribbon (i.e., flusn or sunken).
  Select Case control.id
    Case Is = "TB1"

      If Not ActiveWindow.View.ShowBookmarks Then
        toggleState = True
      Else
        toggleState = False
      End If
    Case Is = "TB2"
      If Not ActiveWindow.View.ShowHiddenText Then
        toggleState = True
      Else
        toggleState = False
      End If
  End Select
End Sub

§   Plak de volgende code in Macros:

Option Explicit

Sub ShowEditor()
ShowVisualBasicEditor = True
End Sub

Sub Macro1()
MsgBox "Macro 1 running" 'Replace this with whatever code you would wish to run.
End Sub

Sub Macro2()
MsgBox "Macro 2 running" 'Replace this with whatever code you would wish to run.
End Sub

Sub Macro3()
MsgBox "Macro 3 running" 'Replace this with whatever code you would wish to run.
End Sub

§   Sla de sjabloon op.
§   Sluit deze.
§   Sluit Word.
§   Zet de sjabloon in de start-up directory van Word.
§   Open Word.
§   Test de zelfgemaakte knoppen.

1.5     Voorbeeld 4

In onderstaand voorbeeld bepaalt de property startFromScratch of de tab als enige op het lint tevoorschijn komt of niet (True = als enige; False = naast de andere tabs).

De property insertBeforeMso bepaalt op welk plek de tab tevoorschijn komt.

<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
  <ribbon startFromScratch="false">
    <tabs>
      <tab id="OME" label="OME" keytip="OME" insertBeforeMso="TabHome">
         <group id="Zaaknummers" label="Zaaknummers">
           <button id="ZaaknummersAanpassen" label="Zaaknummers aanpassen" imageMso="HappyFace" size="large" onAction="ctlZaaknummersAanpassen" />
         </group>
         <group id="Brievenmacros" label="Brievenmacro's">
           <button id="OpenenVordering" label="Openen vordering" imageMso="FileOpen" size="large" onAction="ctlOpenenVordering" />
           <button id="NieuwePagina" label="Nieuwe pagina" imageMso="FileNew" size="large" onAction="ctlNieuwePagina" />
           <button id="RegelsWeghalen" label="Regels weghalen" imageMso="InkEraseMode" size="large" onAction="ctlRegelsWeghalen" />
           <button id="PrintenEnkel" label="Printen enkel" imageMso="FilePrint" size="large" onAction="ctlPrintenEnkel" />
           <button id="PrintenMeer" label="Printen meer" imageMso="PageSetupPageDialog" size="large" onAction="ctlPrintenMeer" />
         </group>
      </tab>
    </tabs>
  </ribbon>
</customUI>

De tab OME ziet er dan zo uit:


1.6     Zelfgemaakte tabs in de Office 2010 Backstage View

Om dit voormekaar te krijgen, hebben we een iets andere opbouw van het XML bestand nodig.
Onderstaande is een voorbeeld van XML code voor het aanpassen van de Backstage view.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
   <backstage>
      <tab id="customTab" label="Sample Tab">
         <firstColumn>
             <group id="customGroup" label="Custom Group">
                <topItems>
                   <button id="customButton" label=" Load &amp;&amp; Return" imageMso="BevelShapeGallery" onAction="OnAction" isDefinitive="true" />
                </topItems>
             </group>
          </firstColumn>
       </tab>
   </backstage>
</customUI>

Nog een voorbeeld:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" >
   <backstage>
      <button id="saveBtn" label="Load &amp;&amp; Return" imageMso="SourceControlCheckIn" keytip="Z" insertAfterMso="FileSaveAs" onAction="OnAction" isDefinitive="true" />
   </backstage>
</customUI>

Met bijbehorend VBA:

Sub OnAction(control As IRibbonControl)
    Dim wdApp As Word.Application
   
    Set wdApp = GetObject(, "Word.Application")
    wdApp.Documents.Open FileName:="C:\< your path here>\MyResume.dotx", ReadOnly:=True, AddtoRecentFiles:=False
End Sub

1.7     Overzicht van de plaatjes voor de knoppen

Dit kunnen we vinden via de link http://soltechs.net/CustomUI/imageMso01.asp


Reacties

Populaire posts van deze blog

Excel: VBA script om wachtwoord te verwijderen

Af en toe krijg ik een vraag om een wachtwoord van een Excel blad te halen. Doodsimpel met VBA. Hier een script dat ik gebruik: Sub WachtwoordCrack()     Dim a As Integer, b As Integer, c As Integer, d As Integer, _     e As Integer, f As Integer, g As Integer, h As Integer, _  I As Integer, j As Integer, k, m As Integer     Dim begin As Date, eind As Date     Dim duur As String     Dim objSheet As Worksheet     begin = TimeValue(Time)     On Error Resume Next     For Each objSheet In Application.Worksheets         For a = 65 To 66: For b = 65 To 66: For c = 65 To 66             For d = 65 To 66: For e = 65 To 66: For f = 65 To 66                 For g = 65 To 66: For h = 65 To 66: For I = 65 To 66                     For j = 65 To 66: For k = 65 To 66: For m = 32 To 126                         ActiveSheet.Unprotect Chr(a) & Chr(b) & _   Chr(c) & Chr(d) & Chr(e) & Chr(f) & _   Chr(g) & Chr(h) &  Chr(I) & Chr(j) & C

Excel 2013: uniek aantal in draaitabel

Tot en met versie 2010 was het in Excel lastig om in een draaitabel een uniek aantal (DISTINCT COUNT) te tellen. We geven een voorbeeld op basis van een verkoperslijst. In deze lijst kunnen we zien welke verkopers welke artikelen hebben verkocht. Willen we nu in een draaitabel laten zien hoeveel artikelen een verkoper heeft verkocht, dan krijgen we wel de aantallen maar niet de unieke aantallen te zien. Om toch de unieke aantallen te laten zien, hebben we een aantal stappen nodig. Op het moment dat we de draaitabel invoegen, krijgen we in Excel 2013 dit dialoogvenster: Onderaan zien we daar een nieuwe optie: Deze gegevens toevoegen aan het gegevensmodel . Deze optie moeten we aanvinken, voor we op OK klikken. We krijgen dan een iets ander beeld dan normaal: Normaliter krijgen we alleen de veldnamen. Nu zien we er het woord Bereik boven staan. Voor het voorbeeld heb ik nu Verkoper toegevoegd aan Rijen en Artikelomschrijving aan Waarden . Het resultaat is identiek

Excel: laatste datum voor een groep, draaitabel of matrixformule?

Via een Excel groep krijg ik de vraag hoe je de laatste datum voor een groep er uit kunt pikken. We geven hier even de voorbeelddata: Voor zover ik kan zien zijn er in ieder geval twee mogelijkheden: met matrixformules en met een draaitabel . Oplossing: draaitabel We zullen het in dit voorbeeld maar even helemaal volgens de regels van de Excel kunst doen. Voor het maken van de draaitabel heb ik de lijst eerst omgezet naar een tabel ( INVOEGEN => DRAAITABEL ). De naam veranderen we dan even van Tabel1 in draaitabel . Vervolgens maken we de draaitabel. Via Waardeveldinstellingen kiezen we dan voor het datumveld voor Max en bij Getalnotatie voor Datum . De kopjes zetten we even om naar Naam en Laatste datum . Klaar. Oplossing: matrixformules Voor dat we de matrixformules gaan maken, creëren we eerst namen met flexibele bereiken: datum =VERSCHUIVING(Blad1!$B$2;0;0;AANTALARG(Blad1!$B:$B)-1;1) naam =VERSCHUIVING(Blad1!$A$2;0;0;AANTALARG(Blad1!$A:$A