Schreibbüro Richter

Textfeld einfügen ohne Rahmen/Rand

Wer häufig Textfelder in Word einfügt, beispielsweise für Marginalien am Rand, wünscht sich früher oder später, die Umrandung des Feldes default ausschalten zu können, um nicht bei jedem einzelnen neuen Textfeld zuerst den Rand ausschalten zu müssen. Dafür bietet sich zunächst in der Symbolleiste Zeichnen im Dialogfeld Zeichnen die Option Als Standard für Autoform festlegen an. Leider funktioniert das nur so lange, bis ein Pfeil oder eine Linie einzufügen ist. Schaltet man nämlich für die Textfelder den Rand aus und definiert dies als Standard, so sind die folgenden Pfeile und Linien default nicht zu sehen, womit die Option für diesen Zweck definitiv unbrauchbar ist.

Die folgende Routine ist genau zu diesem Zweck gedacht: Sie fügt wie gewohnt ein Textfeld ein, das jedoch voreingestellt keinen Rahmen hat. Man bringt die Prozedur am besten in einem eigenen Modul unter und weist der Prozedur »NeuesTextfeld« z. B. eine → Schaltfläche in der Menüleiste zu. Dann hat man bei jedem Textfeld die Wahl, ob mit oder ohne Rahmen.

Der grundlegende Code, der die Realisierung des lange gehegten Plans ermöglichte, stammt von Peter Marchert, dem ich an dieser Stelle herzlich danke.

VBA-Routine in Word zum Einfügen eines Textfeldes ohne Rand (32-Bit-Versionen von Word ab Word 2000)

So ist die folgende Routine ein echtes Gemeinschaftswerk und läuft unter 32-Bit-Versionen ab Word 2000. Die Routine ist nach wie vor nützlich, denn auch in Word 2016 muss beim Einfügen neuer Textfelder über die Benutzerschnittstelle jedesmal der Rahmen erst entfernt werden. Die Default-Einstellung lässt sich nicht ändern. Soll sie unter 64-Bit-Versionen von Word laufen, müssen die API-Funktionen SetTimer und KillTimer mit PtrSafe für 64 Bit deklariert werden.


Option Explicit
'============================================================================  
' Windowstimer setzen  
'============================================================================  
Declare Function SetTimer Lib "user32" _  
    (ByVal hwnd As Long, _  
    ByVal nIDEvent As Long, _  
    ByVal uElapse As Long, _  
    ByVal lpTimerFunc As Long) _  
As Long  

'============================================================================  
' Windowstimer löschen  
'============================================================================  
Declare Function KillTimer Lib "user32" _  
    (ByVal hwnd As Long, _  
    ByVal nIDEvent As Long) As Long  

Public Const lngAPITIMER    As Long = &H10000   
Public lngTIMERID           As Long   

Sub NeuesTextfeld()  
    On Error Resume Next    
    '------------------------------------------------------------------------  
    ' Ruft den Befehl Einfügen Textfeld auf.  
    '------------------------------------------------------------------------  
    CommandBars.FindControl(ID:=139).Execute   
    lngTIMERID = SetTimer(0, lngAPITIMER, 100, AddressOf Timer_Procedure)   
    '------------------------------------------------------------------------  
    ' Startet den Windowstimer und ruft alle 100 Millisekunden die Prozedur  
    '------------------------------------------------------------------------  
End Sub  

Public Sub Timer_Procedure()  
    On Error Resume Next   
    '------------------------------------------------------------------------  
    ' Wenn die Markierung im Textfeld steht, ist das Textfeld eingefügt worden.  
    ' Nun wird der Timer gelöscht, und es kann weitergehen mit dem Ausblenden des Randes.  
    ' Dieser Teil und die Adaption stammen von Nora Richter aka Lisa.  
    '------------------------------------------------------------------------  
    If Selection.StoryType = wdTextFrameStory Then   
        KillTimer 0, lngTIMERID   
        With Selection   
            .ShapeRange.Line.Visible = msoFalse   
            .ShapeRange.TextFrame.MarginLeft = 0#   
            .ShapeRange.TextFrame.MarginRight = 0#   
            .ShapeRange.TextFrame.MarginTop = 0#   
            .ShapeRange.TextFrame.MarginBottom = 0#   
            .Collapse   
        End With   
    End If   
End Sub  

Mit VBA in Word Textfeld ohne Rand einfügen (ab Word 97 bis Word 2003)

Die Prozedur wurde vor vielen Jahren im Forum gebaut. Um sie auch unter Word 97 zum Laufen zu bringen, hat MVP Max Kaffl (aka Nepumuk) den AddressOf-Operator nachgebaut, der die Nutzung auch unter MS Word 97 (Word 8 unter VBA 5) sicherstellt. Im Anschluss findet sich die vollständige Routine.


Option Explicit   

#If VBA6 = False Then   
    '============================================================================  
    ' Alternative um die AddressOf() -Fkt. unter Office 97 zu ersetzen  
    ' bedingt kompiliert, damit auch unter VBA5 lauffähig  
    '============================================================================  
    Private Declare Function GetCurrentVbaProject Lib "vba332.dll" Alias "EbGetExecutingProj" ( _  
        ByRef hProject As Long) As Long  
    Private Declare Function GetFuncID Lib "vba332.dll" Alias "TipGetFunctionId" ( _  
        ByVal hProject As Long, _  
        ByVal strFunctionName As String, _  
        ByRef strFunctionId As String) As Long  
    Private Declare Function GetAddr Lib "vba332.dll" Alias "TipGetLpfnOfFunctionId" ( _  
        ByVal hProject As Long, _  
        ByVal strFunctionId As String, _  
        ByRef lpfn As Long) As Long  
#End If   

'============================================================================  
' Windowstimer setzen  
'============================================================================  
Declare Function SetTimer Lib "user32" _  
    (ByVal hwnd As Long, _  
    ByVal nIDEvent As Long, _  
    ByVal uElapse As Long, _  
    ByVal lpTimerFunc As Long) _  
As Long  

'============================================================================  
' Windowstimer löschen  
'============================================================================  
Declare Function KillTimer Lib "user32" _  
    (ByVal hwnd As Long, _  
    ByVal nIDEvent As Long) As Long  

Public Const lngAPITIMER    As Long = &H10000   
Public lngTIMERID           As Long   

#If VBA6 = False Then   
    Public Function AddrOf(strFuncName As String) As Long  
        ' Nachbau von Max Kaffl aka Nepumuk für den Operator AddressOf aus VBA 6  
        ' gibt den Funktionszeiger einer public VBA Funktion zurück  
        ' Parameter: strFuncName ... Funktionsname  
        ' Return: >0 Adresse, 0 Fehler  
        ' Aufruf zb lFuncPtr& = AddrOf("MyPublicFunc")  
       
        Dim hProject As Long, lResult As Long, lpfn As Long   
        Dim strID As String, strFuncNameUnicode As String   
       
        Const NO_ERROR = 0   
        AddrOf = 0   
       
        ' Konvert strFuncName Unicode  
        strFuncNameUnicode = StrConv(strFuncName, vbUnicode)   
       
        ' Handle des VBA - Moduls holen  
        Call GetCurrentVbaProject(hProject)   
       
        If hProject <> 0 Then   
            ' FunktionsID der VBA-Funktion ermitteln  
            lResult = GetFuncID(hProject, strFuncNameUnicode, strID)   
            If lResult = NO_ERROR Then   
                ' Adresse des FunktionsID holen  
                lResult = GetAddr(hProject, strID, lpfn)   
                If lResult = NO_ERROR Then: AddrOf = lpfn   
            End If   
        End If   
       
    End Function  
#End If   

Sub NeuesTextfeld()  
    On Error Resume Next    
    '------------------------------------------------------------------------  
    ' Ruft den Befehl Einfügen Textfeld auf.  
    '------------------------------------------------------------------------  
    CommandBars.FindControl(ID:=139).Execute   
    #If VBA6 = False Then   
        lngTIMERID = SetTimer(0, lngAPITIMER, 100, AddrOf("Timer_Procedure"))   
    #Else   
        lngTIMERID = SetTimer(0, lngAPITIMER, 100, AddressOf Timer_Procedure)   
    #End If   
        '------------------------------------------------------------------------  
        ' Startet den Windowstimer und ruft alle 100 Millisekunden die Prozedur  
        ' "Timer_Procedure" auf, die rote Anzeige für Syntax erscheint offenbar,  
        ' weil AddressOf für andere Bezeichnung reserviert ist, läuft trotzdem.  
        '------------------------------------------------------------------------  
End Sub  

Public Sub Timer_Procedure()  
    On Error Resume Next   
    '------------------------------------------------------------------------  
    ' Wenn die Markierung im Textfeld steht, ist das Textfeld eingefügt worden.  
    ' Nun wird der Timer gelöscht, und es kann weitergehen mit dem Ausblenden des Randes.  
    ' Dieser bescheidene Teil und die Adaption stammen von Nora Richter aka Lisa.  
    '------------------------------------------------------------------------  
    If Selection.StoryType = wdTextFrameStory Then   
        KillTimer 0, lngTIMERID   
        With Selection   
            .ShapeRange.Line.Visible = msoFalse   
            .ShapeRange.TextFrame.MarginLeft = 0#   
            .ShapeRange.TextFrame.MarginRight = 0#   
            .ShapeRange.TextFrame.MarginTop = 0#   
            .ShapeRange.TextFrame.MarginBottom = 0#   
            .Collapse   
        End With   
    End If   
End Sub  

Textfeld ohne Rand ab Word 2007 als Textbaustein (ohne VBA, Update)

Ab Word 2007 kann man ein Textfeld zwar immer noch nicht default ohne Rand bzw. ohne Rahmen einfügen. Man hat jedoch eine Möglichkeit über die Benutzerschnittstelle, ein nach eigenen Wünschen formatiertes Textfeld (eben auch ohne Rand) etwa zur Verwendung in einer Marginalienspalte als Textbaustein in der Buildingblocks.dotx zu speichern und dann komfortabel zu verwenden. Diese Möglichkeit habe ich anhand eines Positionsrahmens für Grafiken mit Beschriftung beschrieben, was für ein Textfeld analog angewendet werden kann, Beispieldokument mit Textfeld ohne Rahmen als Schnellbaustein.