Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
824to828
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
824to828
824to828
Aktuelles Verzeichnis
Verzeichnis Index
Verzeichnis Index
Übersicht Verzeichnisse
Inhaltsverzeichnis

Fehler im Code, aber wo?

Fehler im Code, aber wo?
07.12.2006 15:28:51
Boris
Hiho,
werde gerade wahnsinnig mit folgender Sache: In ein Sheet werden (über worksheet_change) 2 Fotos eingefügt (variabel nach einer ID) und diese mit "Bild1" und "Bild2" benannt.
Falls die Bilder nicht vorhanden sind, wird die 'Sub' mit "On Error goto usw" abgebrochen. Ändert man nun die ID, sollen die alten Bilder gelöscht und die neuen eingefügt werden.

Sub Worksheet_Change(ByVal Target As Range)
If Target.Address <> "$A$1" Then Exit Sub
BilderLöschen
BilderEinfügen
End Sub

Falls die Bilder nicht vorhanden sind, liefert mir folgende 'Sub' (in Module1) den Fehler "Run-time error: Unable to get the Pictures property of the worksheet class". Ersetze ich Pictures durch Shape, kommt: "Unable to find the specified ..." und zwar für i=2.

Sub BilderLöschen()
Dim i As Integer
For i = 1 To 2
On Error GoTo WEITER
Sheets("PIS").Pictures("Bild" & i).Delete
WEITER:
Next i
End Sub

Sollte On Error goto Weiter nicht bei einem Nichtvorhandensein zu WEITER springen, und dort die if-Schleife verlassen, da i=2 ist?
Wo ist der Fehler...?

16
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Fehler im Code, aber wo?
07.12.2006 15:36:15
ChrisL
Hallo Boris
Fehler sehe ich auch nicht, aber ich würde mit Objekten anstelle von Namen arbeiten z.B.

Sub Makro1()
Dim pic As Object
For Each pic In ActiveSheet.Pictures
pic.Delete
Next pic
End Sub

Gruss
Chris
AW: Fehler im Code, aber wo?
07.12.2006 15:50:23
Boris
Ui, das übersteigt nun meine VBA-Kenntnisse (die fast gegen null gehen)...
Das Problem: ich möchte nur die Bilder/Objekte löschen/aktualisieren, die auch mit worksheet_change variabel eingefügt werden. Alle anderen Objekte (Logos, Charts, usw.) sollen nicht gelöscht werden.
Sollte ich Datei mit genauer Erklärung hochladen?
Anzeige
AW: Fehler im Code, aber wo?
07.12.2006 16:24:28
ChrisL
Hallo Boris
Ui ui ui, dann vielleich doch so... :-)

Sub Makro2()
On Error Resume Next
Worksheets("PIS").Shapes("Picture 1").Delete
End Sub

Bei mir lautet der Name auf Picture nicht Bild. Sowieso...
"Picture 1" nicht "Picture1"
"Bild 1" nicht "Bild1"
Bedeutet:
Sheets("PIS").Pictures("Bild " & i).Delete
nicht
Sheets("PIS").Pictures("Bild" & i).Delete
Gruss
Chris
AW: Fehler im Code, aber wo?
07.12.2006 17:14:53
Boris
Hi Chris,
habe jetzt das On Error Resume Next in meinen Code eingebaut. Das ganze sieht jetzt so aus, und es funktioniert fast alles (allerdings habe ich das mit "...Makro1 ... Objekt..." noch nicht verstanden). Hier mal ein Bild:
Userbild
Und das ist der Code in Module1:
Option Explicit
Sub BilderEinfügen()
Dim i As Integer
On Error Resume Next
For i = 2 To 3
Sheets("PIS").Pictures.Insert(Range("M" & i).Value).Select
With Selection
.Top = Range(Range("N" & i).Value).Top
.Left = Range(Range("N" & i).Value).Left
.Width = Range(Range("N" & i).Value & ":" & Range("O" & i).Value).Width
.Height = .Width * 3 / 4
.Name = "Bild" & i
End With
Next i
On Error GoTo 0
End Sub
Sub BilderLöschen()
Dim i As Integer
On Error Resume Next
For i = 2 To 3
Sheets("PIS").Pictures("Bild" & i).Delete
Next i
On Error GoTo 0
End Sub
In ThisWorkbook steht:

Private Sub Workbook_Open()
BilderEinfügen
End Sub


Private Sub Workbook_BeforeClose(Cancel As Boolean)
BilderLöschen
End Sub

und in Sheet(PIS):
Sub Worksheet_Change(ByVal Target As Range)
If Target.Address "$A$1" Then Exit Sub
BilderLöschen
BilderEinfügen
Range("A1").Select
End Sub
Das ganze funktioniert (bis auf eine Kleinigkeit, die ich weiter unten erkläre), d.h. wird die Datei geöffnet, werden die Bilder ins Sheet "PIS" eingefügt. Bei Veränderungen der Zelle A1 werden die Bilder gelöscht und die neuen eingefügt, Fehlermeldungen (Bild nicht vorhanden) werden ignoriert. Beim Schliessen der Datei werden die Dateien gelöscht. Fragen:
1) Kann man das noch besser schreiben? Was meintest Du mit Dim Pic as Objekt?
2) Aktiviere ich nun das Sheet "Start" und schliesse die Datei, werden die Bilder gelöscht (erkennbar an der Dateigröße). Öffne ich nun die Datei wieder, ist Sheet "Start" aktiv, wechsle ich nun zu "PIS", sind die Bilder nicht geladen? Wieso? Eigentlich müssten doch durch workbook_open die Bilder in Sheets("PIS") eingefügt werden...
Ganz schön langer Beitrag...
Grüße,
Boris
Anzeige
AW: Fehler im Code, aber wo?
07.12.2006 17:46:01
ChrisL
Hallo Boris
Um den Fehler richtig zu suchen/analysieren müsste ich die Mappe neu erstellen, wozu ich gerade keinen Bock habe :-)
Schuss ins Blaue...

Sub BilderEinfügen()
Dim i As Integer
On Error Resume Next
For i = 2 To 3
Sheets("PIS").Pictures.Insert(Sheets("PIS").Range("M" & i).Value).Select
With Selection
.Top = Sheets("PIS").Range(Sheets("PIS").Range("N" & i).Value).Top
.Left = Sheets("PIS").Range(Sheets("PIS").Range("N" & i).Value).Left
.Width = Sheets("PIS").Range(Sheets("PIS").Range("N" & i).Value & ":" & Sheets("PIS").Range("O" & i).Value).Width
.Height = .Width * 3 / 4
.Name = "Bild" & i
End With
Next i
On Error GoTo 0
End Sub

Was ich mit Objekt usw. meinte betrifft den richtigen Umgang mit Variablen. Das Bild hat zwar einen Namen (Text-String) aber im Prizip ist es ja kein Text sondern eben ein Bild (Objekt). Das gleiche gilt z.B. auch für Bereiche, z.B. "A1:C3" ist zwar ein String, aber eigentlich sprichst du die Range an.
https://www.herber.de/xlfaq/xlbasics/main_var.htm
Ist aber alles egal, denn auch Deine Methode ist prinzipiell möglich.
Gruss
Chris
Anzeige
AW: Fehler im Code, aber wo?
07.12.2006 18:17:21
Boris
Hi Chriss,
schonmal Vielen Dank für die Hilfe. Der Schuss ins Blaue hat zwar leider nicht geklappt, aber das werde ich durch Tüfteln schon irgendwie lösen.
Das mit der Variablen-Deklaration schaue ich mir demnächst mal an.
Kann man eigentlich folgendes verwenden:

Sub test()
Dim Bla as String
Bla = Sheets("PIS")
Bla.Range("...").Select
End Sub

Oder löst man das eleganter über eine with schleife?
AW: Fehler im Code, aber wo?
07.12.2006 18:36:45
ChrisL
Hallo
Bla ist in diesem Fall eine Objektvariable (wieder beim Thema), die mit "Set" iniziert werden muss. Beispiel:

Sub t()
Dim WS As Worksheet
Dim rng As Range
Set WS = Worksheets("PIS")
Set rng = WS.Range("A1")
rng = "test"
MsgBox rng
End Sub

Betr. Schleife ein kleines Beispiel:
Cells(Zeile, Spalte) d.h. wird Bereich A1:A3 durchlaufen.

Sub tt()
Dim i As Byte
For i = 1 To 3
MsgBox Sheets("PIS").Cells(i, 1)
Next i
End Sub

Gruss
Chris
PS: Noch ein Schuss ins Blaue. Anstelle Workbook_Open ein Worksheet_Activate Ereignis.
Anzeige
AW: Fehler im Code, aber wo?
08.12.2006 11:56:41
Boris
Hallo Chris,
danke für die guten Anregungen, habe die Themen Selektieren usw. gelesen. Klingt sehr logisch. Allerdings kommt auch einige Verwirrung auf, wenn man versucht VBA im Selbststudium zu lernen und gleichzeitig in der Praxis anwendet. Habe auch (noch) Probleme wo man welche 'Sub/Ereignis' programmiert und wie man am besten mit Variablen umgeht (global/lokal) usw...
Hier noch einige Fragen:
1) Was ist der Unterschied zwischen
Dim WS As Worksheet
Set WS = Worksheets("PIS")
WS.Range("A1") = "Lala"
und
With Worksheets("PIS")
.Range("A1") = "Lala"
End With?
Bzw. welche Lösung ist eleganter?
2) Ist es sinnvoll WS = Worksheets("PIS") in Module1 oben im Deklarationsteil zu definieren, so dass man in allen Subs darauf zugreifen kann? Könnte man so auch einbauen, dass WS umbenannt wird, wenn jemand das entsprechende Tabellenblatt umbenennt?
3) Kann man ein Objekt auch ohne es zu selektieren positionieren und anpassen? Also diese Select-Anweisung umgehen:
Sheets("Property Overview").Pictures.Insert(Range("Q" & i).Value).Select
With selection
...
End With
Hm, ich glaube das wars erstmal...
Grüße,
Boris
Anzeige
AW: Fehler im Code, aber wo?
08.12.2006 13:35:44
ChrisL
Hallo Boris
Ich probiere mal die verschiedenen Fragen zu beantworten.
1)
Im Resultat kein Unterschied. Als einfache Faustregel würde ich sagen, sollte die Variante gewählt werden, wo am wenigsten Buchstaben geschrieben werden müssen. In deinem Beispiel ist es die erste Variante. Wenn du aber viele verschiedene Vorgänge mit dem gleichen With-Block abhandeln kannst, dann würde ich diese wählen. Z.B.
With Worksheets("PIS")
.Range("A1") = "Lala"
.Range("A2").NumberFormat = "0"
.Columns(1).Visible = False
'usw.
End With
So macht der With-Block Sinn, aber "nur" mit einem Befehl (Range(..)="lala") nicht unbedingt.
Jeder hat seine eigenen Vorlieben und das soll auch so sein. Für Personen deren Job das Programmieren ist, ist jedoch Effizienz (möglichst kurze, übersichtliche Codes) entscheidend.
2)
Die Frage, ob Variablen Global oder nicht deklariert werden sollen, hängt von deren Verwendung ab. Persönlich verwende ich mit ganz wenigen Ausnahmen nie globale Variabeln, da Variablen bei Bedarf auch anderweitig von Prozedur zu Prozedur/Funktion übergeben werden können.
Meine Faustregel (gibt vermutlich auch andere Ansichten): Wenn immer möglich auf globale Variablen verzichten.
Betreffend Umbenennen: Global hätte den Vorteil, dass du den Blattnamen nur einmal bezeichnest. Anderseits müsstest du trotzdem den Code anpassen, wenn jemand den Namen verändert. Diesbezüglich gibt es m.W. 2 Möglichkeiten:
- Entweder bezeichnest du die Blätter mit dem Namen, dann musst du ggf. Code ändern.
- Oder du gibst den Index an z.B. Worksheets(1) = erstes Tabellenblatt in der Mappe.
3)
Ja ist möglich und m.E. sehr zu empfehlen

Sub t()
With Sheets("Property Overview").Pictures.Insert(Range("Q" & i).Value)
End With
End Sub

oder

Sub tt()
Dim obj As Object
Set obj = Sheets("Property Overview").Pictures.Insert(Range("Q" & i).Value)
With obj
End With
End Sub

N.b. achte auf eine konsequente Bezeichnung deiner Tabellenblätter. Nicht nur das Tabellenblatt mit dem Picture, sondern auch
Range("Q" & i).Value
Ohne nähere Bezeichnung wird das gerade aktive Arbeitsblatt angesprochen, wo der Wert evtl. Null ist. Darauf zielte mein erfolgloser Schuss ins Blaue.
Gruss
Chris
Anzeige
AW: Fehler im Code, aber wo?
08.12.2006 14:33:38
Boris
Hallo Chris,
ich merke gerade, dass ich durch diese "Diskussion" extrem viel lerne. Sehr schön...
So sieht der Code jetzt aus (diesmal aus der Original-Datei, deshalb sind die Bezüge anders), bei dem auch "der Schuss ins Blaue" funktioniert:
Option Explicit
Dim WS As Worksheet
Dim objBilder As Object

Sub BilderEinfügen()
Set WS = Worksheets("Property Overview")
Dim i As Integer
Application.ScreenUpdating = False
On Error Resume Next
For i = 2 To 5
Set objBilder = WS.Pictures.Insert(WS.Range("Q" & i).Value)
With objBilder
.Top = WS.Range(WS.Range("R" & i).Value).Top
.Left = WS.Range(WS.Range("R" & i).Value).Left
.Width = WS.Range(WS.Range("R" & i).Value & ":" & WS.Range("S" & i).Value).Width
.Height = .Width * 3 / 4
.Name = "Bild" & i
End With
Next i
On Error GoTo 0
Application.ScreenUpdating = True
End Sub


Sub BilderLöschen()
Set WS = Worksheets("Property Overview")
Dim i As Integer
Application.ScreenUpdating = False
On Error Resume Next
For i = 2 To 5
WS.Pictures("Bild" & i).Delete
Next i
On Error GoTo 0
Application.ScreenUpdating = True
End Sub

Ich frage mich auch laufend, ob es sinnvoll ist, diverse Bezeichnungen, Pfadangaben usw. ins Tabellenblatt zu schreiben und diese in VBA zu übernehmen. Ich tue dies, damit gewisse Informationen direkt im Tabellenblatt zu erkennen sind...
Noch etwas anderes: Warum funktioniert das hier nicht:
Option Explicit
Dim WS As Worksheet
Dim objBilder As Object
Set WS = Worksheets("Property Overview") (((hier kommt ein Fehler)))

Sub BilderEinfügen()
Verwendung von WS
End Sub


Sub BilderLöschen()
Verwendung von WS
End Sub

Vielleicht sollte ich erstmal den Teil über die Variablen-Deklaration lesen...
Grüße,
Boris
Anzeige
AW: Fehler im Code, aber wo?
08.12.2006 15:34:50
ChrisL
Hallo Boris
Freut mich, dass die Diskussion Früchte trägt :-)
Set... muss in eine Prozedur verschoben werden. Allenfalls im Workbook_Open Ereignis. Die globale Deklaration muss allerdings weiterhin im Modul sein.
Allerdings würde ich auf globale Deklaration verzichten. Mittels folgendem Ansatz definierst du das Tabellenblatt einmalig im "Hauptmakro" und übergibst die Variablen an die "Unterprozeduren". Wenn du für Prozeduren "Private" verwendest, dann kannst du diese nur innerhalb vom gleichen Modul ansprechen. Private hat den Vorteil, dass diese unter "Extras/Makros" nicht ersichtlich sind (müssen auch nicht, weil sowieso nur aus dem Hauptmakro heraus verwendet).
Sub test()
Dim WS As Worksheet
Set WS = Worksheets("Property Overview")
Call BilderLöschen(WS)
Call BilderEinfügen(WS)
End Sub

Private Sub BilderLöschen(WS As Worksheet)
MsgBox WS.Name
End Sub


Private Sub BilderEinfügen(WS As Worksheet)
MsgBox WS.Name
End Sub

Gruss
Chris
Anzeige
AW: Fehler im Code, aber wo?
08.12.2006 16:39:28
Boris
Tut mir ja leid, aber es tauchen plötzlich aus dem Nichts folgende Fragen auf:
In Sheet(Property Overview) steht nun das:

Private Sub Worksheet_Change(ByVal Target As Range)
Dim WS As Worksheet
Set WS = Worksheets("Property Overview")
If Target.Address <> "$B$1" Then Exit Sub
Call BilderLöschen(WS)
Call BilderEinfügen(WS)
End Sub

Und in Module1:
Dim objBild As Object
Sub BilderEinfügen(WS As Worksheet)
Dim i As Integer
Application.ScreenUpdating = False
On Error Resume Next
For i = 2 To 5
Set objBild = WS.Pictures.Insert(WS.Range("Q" & i).Value)
With objBild
.Top = WS.Range(WS.Range("R" & i).Value).Top
.Left = WS.Range(WS.Range("R" & i).Value).Left
.Width = WS.Range(WS.Range("R" & i).Value & ":" & WS.Range("S" & i).Value).Width
.Height = .Width * 3 / 4
End With
Next i
On Error GoTo 0
Application.ScreenUpdating = True
End Sub
Sub BilderLöschen(WS As Worksheet)
Dim i As Integer
Application.ScreenUpdating = False
For Each objBild In WS.Pictures
objBild.Delete
Next objBild
Application.ScreenUpdating = True
End Sub
1) Zum einen habe ich in BilderLöschen die For-Schleife ersetzt, funktioniert einwandfrei, deshalb ist objBild auch global gesetzt, so dass beide Subs darauf zugreifen können.
2) Bezeichne ich allerdings die Subs in Module1 als Private, können diese aus Sheet(Property Overview) nicht mehr aufgerufen werden...?
3) Wenn ich Module1 umbenenne, funktioniert gar nichts mehr? Woran liegt das, würde gerne die Module nach ihrer Funktion benennen, so z.B. Druckmodul, Bildmodul, Kopiermodul.
4) In ThisWorkbook steht nun:

Private Sub Workbook_Open()
Dim WS As Worksheet
Set WS = Worksheets("Property Overview")
Call BilderEinfügen(WS)
End Sub


Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim WS As Worksheet
Set WS = Worksheets("Property Overview")
Call BilderLöschen(WS)
End Sub

d.h. die Übergabe von WS geschieht nun innerhalb von 3 Ereignissen (worksheet_change, workbook_open und workbook_beforeclose). Ist das so sinnvoll?
Falls Dich mein Fragen-Bombardement nervt, würde ich das sogar gut verstehen:) Bitte in diesem Fall um eine klare Ansage:)
Grüße,
Boris
Anzeige
AW: Fehler im Code, aber wo?
08.12.2006 17:43:13
ChrisL
Hallo
Erstmal, nerven tust du nicht, aber das Wochenende naht. ;-)
1)
Global möglich, aber würde trotzdem pro Prozedur deklarieren, da du den Inhalt der Variable gar nicht übergibst d.h. wird in jedem Makro separat gefüllt.
2)
Lass dich betr. Private nicht verwirren. Funktioniert nur, wenn im gleichen Modul darauf zugegriffen wird. Da das Makro aber auch aus ThisWorkbook verwendet werden soll (daran habe ich nicht mehr gedacht), musst du Private weglassen.
3)
Umbenennen sollte möglich sein. Darauf achten, dass du keine Programmbefehle oder bereits verwendete Begriffe als Namen verwendest.
4)
Wenn ich es nun so sehe, muss ich selber zugeben, dass das von mir vorgeschlagene Vorgehen (Variable übergeben) keinen Sinn ergibt. Du könntest je einmal (Einfügen/Löschen) die Variable füllen (so würde ich es tun), oder doch nur einmal, mittels Global und im Open-Ereignis iniziert.
So, habe fertig! :-)
cu
Chris
AW: Fehler im Code, aber wo?
11.12.2006 09:54:11
Boris
Und immer wieder Montags...
Vielen Dank. Deine Ausführungen haben mir sehr geholfen. Habe zwischendurch auch noch einiges getestet bzgl. Variablendeklaration, Übergabe von Variablen, usw...
Die nächste Sache, die ich zu lösen habe steht dann in einem neuen Thread:)
Grüße,
Boris
AW: Fehler im Code, aber wo?
07.12.2006 16:28:10
ramses
Hallo
"...die auch mit worksheet_change variabel eingefügt werden..."
Junge, Junge,... da hast du dir was vorgenommen ?
Wie lange müssen die "variablen" Werte/Bilder denn gültig sein, und wann sollen die gelöscht werden ?
Am Ende der Sitzung, ... irgendwann ?
Da wirst du um eine äusserst trickreiche Array-Verwaltung/Namen Speicherung nicht herum kommen.
Ob sich das hier jemand antut... ?
Gruss Rainer

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige