# Excel 2010 Commandbutton und Label verschoben



## jagga007 (7. Juli 2013)

Hallo Forum,

In meinem Tabellenblatt befinden sich 9 CommandButtons und 3 Labels Bild 004.
In den einschlägigen Foren sind einige Beipielaufgeführt, vieles wurde Diskutiert aber so eine richtige funktionierende Lösung das auch mein Problem beseitigt konnte ich nicht finden.

Bild 003 so sollte es bleiben, doch leider aus irgend einen Grund werden ab und zu CommandButtons verkleinert und irgendwo auf dem Bildschirm verschoben Bild 004.

Die oberen rechten drei Kästchen sind Labels, denn ich wollte sie mit Häckchen versehen und die ander Kästchen sind Rechtecke. Hier möchte ich erwähnen es werden nur immer die oberen drei Labels verschoben, nicht die Rechtecke. Die bleiben an ihren gestzten Platz.

Die CommandBut, die Labels und die Rechtecke sind in den Eigenschaften "von Zellposition und-größe unabhängig" definiert. Auch dieses brachte nicht den erwünschten Erfolg. Nun bin ich mit meinem Latein am Ende und hoffe hier von Euch Hilfe.

Man kann einiges über ähnliche Probleme im Netz lesen, doch so eine richtige funtionierende Lösung die auch meinem Problem hilft konnte ich nicht finden.

Eine Idee von mir wäre noch gewesen eine zusätliche Registerkarte zu erstellen in der die CommondButton jeweils für nur das aktive Tabellenblatt funtionieren denn den Ribbon Creator 2010 und auch den Custom UI Editor hätte ich ja, hab auch schon ein bisschen ausprobiert aber so etwas richtig umzusetzen da haperts.

Diese Datei hab ich geschrieben für mich und meine Kollegen aber außer mir hatt keiner eine Ahnung von VBA in Excel und dann ist es schon etwas unangenehm wenn die Kollegen kommen und sagen Super aber das funktioniert nicht so ganz.

Ich wäre Super Dankbar, wenn ich durch Euch hier eine funktionierende Lösung bekäme.


Gruß
jagga007


----------



## VScan (8. Juli 2013)

Hallo,

das gleiche Problem hab ich auch... 

Kann Dir nur empfehlen, Funktionen zu implementieren, die alle Steuerelemente an der Position halten.

z.B. Bei Sheet_Activate() alle Steuerelemnte mit den gewünschten Positionsangaben zu füttern(Top, Left, Width, Height).

Bei einer "freigegebenen Arbeitsmappe" ist mir sowas bisher nicht passiert, allerdings ist es da auch nicht möglich, die Position eines Steuerelemts per Code zu verändern.


Viele Grüße...


----------



## jagga007 (11. Juli 2013)

Wieso bei einer freigegebenen Arbeitsmappe nicht. Da funktionieren ja meine Makros nicht mehr.
Oder hast du Beispiel für eine Funktion für mich?

Gruß
jagga007


----------



## VScan (11. Juli 2013)

Hallo,

das kommt ganz darauf an, welche Sachen Du ändern möchtest.

Hier ein Link, bei dem alle Einschränkungen von freigegebenen Arbeitsmappen aufgelistet sind. (Unter Punkt "1. Freigeben einer Arbeitsmappe" gibt es einen aufklappbaren Link)
http://office.microsoft.com/de-de/e...itsmappen-zur-zusammenarbeit-HP010096833.aspx

Warum das so ist, weis ich auch nicht, mir ist es halt noch nie passiert, dass sich in dieser Mappe auch beim 1000. Öffnen was verschoben hätte...

Die Makros sehen genauso aus wie bisher, man kann nur bestimmte Sachen einfach nicht machen, da diese gesperrt sind.
Für einige Dinge gibt es Workarounds, 
z.B. Wollte ich zur Laufzeit Charts anlegen und diese befüllen, das geht leider nicht bei einer freigegeben Mappe...
Lösung: Chart anlegen, wenn die Mappe noch nicht freigegeben ist und einfach ausblenden, wenn ich diese dann benötige befüll ich dieses und blende es ein...


Grüße


----------



## VScan (11. Juli 2013)

Was genau funktioniert denn nicht bei Deinen Makros, wenn die Arbeitsmappe freigegeben ist?


----------



## jagga007 (11. Juli 2013)

z. B. meine CommandButtons funktionieren nicht mehr beziehungsweise die Makros werden nicht mehr ausgeführt.

Hast du vielleicht ein Beispiel einer Funktion die die Steuerelemente an Ihrer Position hält?

Kennst du das Control ActiveSheet.Shapes("CommandButton1").Placement = xlMoveAndSize?. Ich Glaube das könnte meine Lösung sein.

Gruß
jagga007


----------



## VScan (12. Juli 2013)

Hey, klar kenn ich das,

hier ein Beispiel...


```
With ActiveSheet.ChartObjects("chartUebersicht")
        .Top = 2.25
        .Left = 22.5
        .Width = 1154.25
        .Height = 441.75
        .Placement = xlFreeFloating
        With .Chart
            'Title
            .HasTitle = True
            .chartTitle.Font.Size = "18"
            .chartTitle.Font.Name = "Arial"
            .chartTitle.Top = 35
            .chartTitle.Left = 369.19
            'Legend
            .HasLegend = False
            'ChartArea
            .PlotArea.InsideTop = 83.7365354330709
            .PlotArea.InsideLeft = 368.8
            .PlotArea.InsideWidth = 776
            .PlotArea.InsideHeight = 343
        End With
    End With
```

Wie gesagt, das funktioniert nur, wenn die Arbeitsmappe nicht freigegeben ist.

Man muss einiges abändern, wenn die Arbeitsmappe freigegeben werden soll.
War aber grundsätzlich kein Problem, da ich für die meisten Dinge, die dann nicht funktionieren ein "Workaround" gefunden habe.
Grundsätzlich würde ich eine Arbeitsmappe aber nicht freigeben, wenn es nicht unbedingt sein muss.


Bei mir werden die Events schon ausgeführt, wenn ich mir das anschauen soll, was nicht funktioniert, brauch ich etwas Code von Dir 

Viele Grüsse...


----------



## jagga007 (13. Juli 2013)

Wie ermittelst du denn die Werte für die .PlotArea? Und wie bau ichs in ein Modul ein, so das es nur einmal geschrieben werden muß. Den in allen Blättern sind die gleichen CommandButton und auch an der gleichen Stelle?



Gruß
jagga007


----------



## VScan (15. Juli 2013)

Hey,

hab hier mal ein kleines Beispiel zusammengestellt...


```
Public Function generateCode_Test() As String
Dim strCode As String
Dim strTop As String
Dim strLeft As String
Dim strWidth As String
Dim strHeight As String
Dim strLegTop As String
Dim strLegLeft As String
Dim strLegFontSize As String
Dim strPlotTop As String
Dim strPlotLeft As String
Dim strPlotWidth As String
Dim strPlotHeight As String
Dim chartName As String
On Error GoTo Exhandler
    'Gewuenschten Chartname der aktiven Sheet angeben ...
    chartName = "topTenChart"
    
    With ActiveSheet.ChartObjects(chartName)
        strTop = Replace(.Top, ",", ".")
        strLeft = Replace(.Left, ",", ".")
        strWidth = Replace(.Width, ",", ".")
        strHeight = Replace(.Height, ",", ".")
        With .Chart
            strLegTop = Replace(.Legend.Top, ",", ".")
            strLegLeft = Replace(.Legend.Left, ",", ".")
            strLegFontSize = .Legend.Font.Size
            strPlotTop = Replace(.PlotArea.InsideTop, ",", ".")
            strPlotLeft = Replace(.PlotArea.InsideLeft, ",", ".")
            strPlotWidth = Replace(.PlotArea.InsideWidth, ",", ".")
            strPlotHeight = Replace(.PlotArea.InsideHeight, ",", ".")
        End With
    End With
    
    strCode = _
    vbTab & "With ActiveSheet.ChartObjects(""" & chartName & """)" & vbCrLf & _
    vbTab & vbTab & ".Top = " & strTop & vbCrLf & _
    vbTab & vbTab & ".Left = " & strLeft & vbCrLf & _
    vbTab & vbTab & ".Width = " & strWidth & vbCrLf & _
    vbTab & vbTab & ".Height = " & strHeight & vbCrLf & _
    vbTab & vbTab & ".Placement = xlFreeFloating" & vbCrLf & _
    vbTab & vbTab & "With .Chart" & vbCrLf & _
    vbTab & vbTab & vbTab & "'Title" & vbCrLf & _
    vbTab & vbTab & vbTab & ".HasTitle = False" & vbCrLf & _
    vbTab & vbTab & vbTab & "'.chartTitle.Font.Size = ""12""" & vbCrLf & _
    vbTab & vbTab & vbTab & "'.chartTitle.Font.Name = ""Arial""" & vbCrLf & _
    vbTab & vbTab & vbTab & "'Legend" & vbCrLf & _
    vbTab & vbTab & vbTab & ".Legend.Top = " & strLegTop & vbCrLf & _
    vbTab & vbTab & vbTab & ".Legend.Left = " & strLegLeft & vbCrLf & _
    vbTab & vbTab & vbTab & ".Legend.Font.Size = " & strLegFontSize & vbCrLf & _
    vbTab & vbTab & vbTab & ".Legend.Font.Name = ""Arial""" & vbCrLf & _
    vbTab & vbTab & vbTab & "'Plot-Area" & vbCrLf & _
    vbTab & vbTab & vbTab & ".PlotArea.InsideTop = " & strPlotTop & vbCrLf & _
    vbTab & vbTab & vbTab & ".PlotArea.InsideLeft = " & strPlotLeft & vbCrLf & _
    vbTab & vbTab & vbTab & ".PlotArea.InsideWidth = " & strPlotWidth & vbCrLf & _
    vbTab & vbTab & vbTab & ".PlotArea.InsideHeight = " & strPlotHeight & vbCrLf & _
    vbTab & vbTab & "End With" & vbCrLf & _
    vbTab & "End With"
    
    generateCode_Test = strCode
Exit Function
Exhandler:
    Debug.Print "Error in generateCode_Test: " & Err.Description
End Function
```

Die Ausgabe sieht dann folgendermaßen aus...


```
With ActiveSheet.ChartObjects("topTenChart")
        .Top = 299
        .Left = 530.5
        .Width = 680
        .Height = 310
        .Placement = xlFreeFloating
        With .Chart
            'Title
            .HasTitle = False
            '.chartTitle.Font.Size = "12"
            '.chartTitle.Font.Name = "Arial"
            'Legend
            .Legend.Top = 260
            .Legend.Left = 569
            .Legend.Font.Size = 8
            .Legend.Font.Name = "Arial"
            'Plot-Area
            .PlotArea.InsideTop = 23
            .PlotArea.InsideLeft = 122
            .PlotArea.InsideWidth = 460
            .PlotArea.InsideHeight = 140
        End With
    End With
```


Anschliessend kannst Du ja einen Parameter zum Makro hinzufügen, damit der chart-name variabel wird.
Das gleiche kann man auch mit CommandButtons machen, allerdings mit unterschiedlichen Attributen, versteht sich ...


Die Erweiterung wäre, sich den Code gleich in ein entsprechendes Modul schreiben zu lassen, was etwa so aussieht...


```
Public Sub generateSizingCode()
Dim cm As CodeModule
Dim vbComp As VBComponent
On Error GoTo Exhandler

    'Hier den Modulnamen angeben, in das der Code geschrieben werden soll
    '(sollte leer sein, sonst wird alles geloescht mit diesem code :)
    Set vbComp = ThisWorkbook.VBProject.VBComponents("mdl_CodeGenTestChart")
    Set cm = vbComp.CodeModule
    
    'loeschen des alten Codes
    If cm.CountOfLines > 0 Then
        cm.DeleteLines 1, cm.CountOfLines
    End If
    
    'Methode aufbauen
    cm.InsertLines cm.CountOfLines + 1, "Option Explicit"
    cm.InsertLines cm.CountOfLines + 1, "Option Compare Text"
    cm.InsertLines cm.CountOfLines + 1, vbCrLf & vbCrLf
    cm.InsertLines cm.CountOfLines + 1, "Public Sub myGeneratedMakro()"
    cm.InsertLines cm.CountOfLines + 1, "On Error GoTo Exhandler"
    
    'Hier der Aufruf unserers Testmakros ...
    cm.InsertLines cm.CountOfLines + 1, generateCode_Test
    
    'Methode abschliessen
    cm.InsertLines cm.CountOfLines + 1, "Exit Sub"
    cm.InsertLines cm.CountOfLines + 1, "Exhandler:"
    cm.InsertLines cm.CountOfLines + 1, vbTab & "Debug.Print ""Error in myGeneratedMakro: "" & Err.Description"
    cm.InsertLines cm.CountOfLines + 1, "End Sub"
    
Exit Sub
Exhandler:
    Debug.Print "Error in generateSizingCode: " & Err.Description
End Sub
```


Viele Grüße, ...


----------



## jagga007 (15. Juli 2013)

Mann oh Mann VScan,

du bist aber ein ganz schöner Fuchs. Du kannst in Foren schaun wo du willst, da wird nichts erwähnt. Du bist nun der erste, der mir in der Richtung ein Beispiel zeigt.

Wie du bereits erwähnt hast, braucht ich das für CommandButton. Da immer für ein aktuelles Monat ca 20 bis 25 Tabellenblätter erstellt werden sind demnach auch in jedem Tabellenblatt diese jeweils 9 Commandbutton. Hast du vieleicht ein Beispiel parat, wo man es besser nachvollziehen könnte?

So sieht die Seite mit CommandButtons aus. Unten kommt nicht mehr viel.

Gruß
jagga007


----------



## VScan (16. Juli 2013)

Einfach die Erste Methode in die jeweiligen Sheets einbauen und die Zweite kann in ein Modul gepackt werden.

Muss natürlich noch angepasst werden, aber ich denke, das ist genau das, was Du suchst 

Grüße...


```
Public Sub setCommandBtns()
    setCommandButtonPositions Me
End Sub


Public Sub setCommandButtonPositions(ByRef actualSheet As Excel.Worksheet)
Dim cmdBtn As Object
On Error GoTo Exhandler
    
    'Iteriere durch alle ActiveX-Controls
    For Each cmdBtn In actualSheet.OLEObjects
        
        'Ist es ein CommandButton?
        If TypeName(cmdBtn.Object) = "CommandButton" Then
            
            'Je nach CommandButton, muss man hier unterscheiden,
            'wo dieser positioniert werden soll ...
            If cmdBtn.Name = "myCommandButton1" Then '<< Hier den "Name" des CommandButtons angeben
                cmdBtn.Top = 10
                cmdBtn.Left = 10
                'cmdBtn...
            ElseIf cmdBtn.Name = "myCommandButton2" Then
                cmdBtn.Top = 10
                cmdBtn.Left = 115
                'cmdBtn...
            ElseIf cmdBtn.Name = "myCommandButton3" Then
                cmdBtn.Top = 10
                cmdBtn.Left = 220
                'cmdBtn...
            End If
            
            'Die Größe ist bei jedem CommandButton gleich ...
            cmdBtn.Width = 100
            cmdBtn.Height = 50
        End If
    Next cmdBtn
Exit Sub
Exhandler:
    Debug.Print "Error in setCommandButtonPositions >> " & Err.Description
End Sub
```


----------



## rodlof (9. September 2013)

Hallo jagga007

Ich habe lange mit dem Problem gekämpft und habe glaube ich den Grund herausgefunden. Die CommandButtons verändern sich, wenn man Sheets druckt oder ein PDF erstellt und nicht 1:1 ausdruckt sondern zum Bsp mit 80% der Originalgrösse. 

Ein ähnliches Problem besteht beim Zuklappen von Zeilen oder Spalten, dort verschwinen nämlich die Tasten (Grösse 0). Ich habe 2 einfache Wege gefunden, um das zu umgehen (weil ich nicht bei jedem Sheet die Position immer im VBA Programmieren will).

1. Vor dem Druck oder vor dem Zuklappen, die Tasten hiden, danach wieder sichtbar machen.
2. Vor dem Druck abspeichern und nach dem Druck schliessen ohne zu speichern, dann ist alles nämlich wieder wie vor dem Druck.

In Code sieht das etwa so aus:

'*Tasten verbergen (werden beim Zeilen verbergen zerstört)
 For i = 1 To 6
    ActiveSheet.Shapes("Taste" & (i)).Visible = False
 Next i

'(Drucken oder PDF oder sonst was )

'*Tasten anzeigen
 For i = 1 To 6
    ActiveSheet.Shapes("Taste" & (i)).Visible = True
 Next i

Hoffe, ich konnte helfen.


----------



## jagga007 (13. September 2013)

Hab heut erst Deine Nachricht gelesen, war berufl. unterwegs. Werds mal ausprobieren wenn es klappt weis ich wieder etwas mehr, wenn nicht dann auch nicht so schlimm. Hab das ganze umgeschrieben und machs nun über eine Userform in der die ganzen Eingaben dann gemacht werden.

Dennoch sehr vielen Dank für Deinen Tipp. 

Gruß
jagga007


----------

