Live-Forum - Die aktuellen Beiträge
Datum
Titel
28.03.2024 21:12:36
28.03.2024 18:31:49
Anzeige
Archiv - Navigation
1852to1856
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
Inhaltsverzeichnis

Dynamischer Button in Multi-User Tabelle

Dynamischer Button in Multi-User Tabelle
09.11.2021 09:04:50
Daniel
Hallo zusammen,
nachdem mir gestern hier so schnell und gut geholfen wurde, heute eine neue Fragestellung.
Ich erzeuge einen dynamischen Button, der in Abhängigkeit der jeweiligen Zellauswahl bei Klick eine gewisse Prozedur auslöst. Das funktioniert tadellos - aber nur im Einzel-User Modus. (Datei gibts hier - erstes Sheet: https://www.herber.de/bbs/user/149009.xlsm)
Sobald ich die Tabelle zur gemeinsamen Bearbeitung freigebe, komm der "Laufzeitfehler 1004 - Die Top-Eigenschaft des OLEObjektes kann nicht festgelegt werden". Mir ist nicht klar, warum Excel das im Multi-User plötzlich verhindert oder blockiert? Was kann ich tun, denn die Tabelle muss verpflichtend im Multi-User laufen. Hier der Code:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Intersect(Target, Range("A5:B1000")) Is Nothing Then
With ActiveSheet
With .CommandButton1
End With
End With
ActiveSheet.CommandButton1.Visible = True
ActiveSheet.CommandButton1.Top = Cells(ActiveCell.Row, 1).Top
ActiveSheet.CommandButton1.Left = Cells(ActiveCell.Row, 1).Left
Else
ActiveSheet.CommandButton1.Visible = False
End If
End Sub
Vielen Dank schonmal vorab ...
LG Daniel Jäger

18
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Dynamischer Button in Multi-User Tabelle
09.11.2021 10:03:16
Daniel
Hi
es gibt Aktionen, die sind im Freigabemodus nicht möglich, bzw verboten, weil das zu inkonsistenten Zuständen führen könnte, oder Microsoft vielleicht nicht eingefallen ist, wie man das sauber und konfliktfrei programmiert.
Wenn damit mehrere Anwender arbeiten, befindet sich der Commandbutton ja vielleicht an unterschiedlichen stellen und das geht nicht.
Da musst du dir was anderes einfallen lassen.
Vielleicht nimmst du, um diese Aktion auszulösen, das BeforeDoubleklick-Event auf die Zellen der Spalte A?
das sollte im Freigabemodus gehen.
Gruß Daniel
AW: Dynamischer Button in Multi-User Tabelle
10.11.2021 11:02:34
Daniel
Hi Daniel,
nach einigen Recherchen bin ich auch zu dem Schluss gekommen, dass ein DoubleKlickEvent auf eine Zelle in Spalte A die einzige Option darstellt (quasi als Behelfs-Button oder Checkbox via Wingdings ...). Mit der Tabelle arbeiten 18 Psychologen, Testleiter und Bürokräfte. Wie müsste mein Code aussehen, damit statt dem Button (der im Multi nicht geht) nun ein farbiges Feld mit Zeichen XY beim Anklicken der nebenstehenden Zelle in Spalte B (wo die Patientennamen stehen) erscheint? Das Ereignis nach Doppelklick auf das erzeugte Farbfeld mit Zeichen XY ist identisch mit dem Code, der auf dem Button liegt:

Private Sub CommandButton1_Click()
Dim MyRow&
MyRow = ActiveCell.Row
If MsgBox("Teilnehmer(in) dauerhaft als beendet markieren?" & Chr(13) & Chr(10) & Chr(13) & Chr(10) & "Achtung:" & Chr(13) & Chr(10) & "- alle vorgesehenen (x) und geplanten (p) Tests werden entfernt" & Chr(13) & Chr(10) & "- erfolgte Tests bleiben erfasst", vbYesNoCancel) = vbYes Then
Application.EnableEvents = False
With Range("A" & ActiveCell.Row & ":" & "B" & ActiveCell.Row).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 255
.TintAndShade = 0
.PatternTintAndShade = 0
End With
With Range("A" & ActiveCell.Row & ":" & "I" & ActiveCell.Row).Font
.Strikethrough = True
.Italic = True
End With
With Range("J" & ActiveCell.Row & ":" & "Z" & ActiveCell.Row)  '  hier nur die range als Bezug
.Replace What:="x", Replacement:=""
.Replace What:="p", Replacement:=""
End With
Range("AA" & ActiveCell.Row & ":" & "AA" & ActiveCell.Row).Value = "Maßnahme beendet"
With Range("AA" & ActiveCell.Row & ":" & "AA" & ActiveCell.Row).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 255
.TintAndShade = 0
.PatternTintAndShade = 0
End With
Else
End If
Application.EnableEvents = True
End Sub

Anzeige
OT: Multi-User Tabelle
09.11.2021 10:05:05
Klaus
Hallo Daniel J,
ich kann dir leider nicht helfen - darum lasse ich den Thread offen.
Aber einen Tipp will ich dir geben: verzichte irgendwie auf Multi-User! Das macht mehr Probleme, als es löst, gerade wenn VBA im Spiel ist.
LG,
Klaus M.
AW: Dynamischer Button in Multi-User Tabelle
09.11.2021 18:20:20
Yal
Hallo Daniel,
ich habe gedacht ... und dann doch gedacht, dass es nicht geht.
Ich übergebe es einfach ins Blaue:
Wenn anstatt eine einzige CommandButton1, das ein- und ausgeblendet werden soll, jede User sein eigene CommandButton bekommt, die vor dem Speichern wieder gelöscht werden sollten, dann lässt sich der Konflikt vielleicht vermeiden ...
VG
Yal
Anzeige
AW: Dynamischer Button in Multi-User Tabelle
10.11.2021 08:36:14
Daniel
Die Idee klingt gut; aber wie löse ich das im VBA? Das übersteigt meine Kenntnisse etwas ... (bin Psychologe)
LG Daniel Jäger
AW: Dynamischer Button in Multi-User Tabelle
10.11.2021 11:33:45
Yal
Hallo Daniel,
Beruf sagt doch über Kompetenzen. Bei Psychologen auch nicht ;-)
Mir scheint der Aufwand für das Nutzen nicht im Verhältnis zu stehen: es geht darum, eine Zustandsänderung einzugeben und daraus die Sichtbarkeit (ganze Zeile gestrichen) zu erhöhen.
Was sind aber die Information? An einem bestimmte Datum wird die Massnahme beendet. Dann sollte irgendwo diese Datum vielleicht eingetragen werden. Dann kann man eine bedingte Formatierung hinlegen, die in Abhängigkeit diese Datum zu heute die ganze Zeile durchstreicht.
Ganze Blatt markieren, Menü "Start", "Bedingte formatierung", "Neue Regel", "Formel zur Ermittlung...", Formel

=UND($A4"";$A4
(Abhängig von der Zelle, die gerade Aktiv ist)
Auf "Formatieren", "Schirft", "Durchgestrichen" anhacken.
Fertig
VG
Yal
Anzeige
AW: Dynamischer Button in Multi-User Tabelle
10.11.2021 11:38:03
Yal
es fehlt ein "nichts". Das macht den Witz kaputt :-(
Beruf sagt doch nichts über Kompetenzen. Bei Psychologen auch nicht ;-)
AW: Dynamischer Button in Multi-User Tabelle
10.11.2021 11:51:27
Daniel
Hi Yal,
diese Überlegung genügt für reine Formatierung - klar. Aber ich möchte nicht noch eine Spalte mit Datum füllen (lassen) müssen, weil das Ende der Maßnahme nur als Status relevant ist. Zudem soll der Button Befehl die geplanten und angedachten Tests aus der Übersicht herausnehmen, damit keine Termine für "Geister"patienten gemacht werden. Die durchlaufenen Tests sollen natürlich drin bleiben, um zu schauen, wieviele Lizenzen über das Jahr so angefallen sind. Das funktioniert bereits. ich bin jetzt auf folgende Lösung über ein Doppelklick Event gestoßen, allerdings nimmt er keine Wingdings-Zeichen (anschaulicher) und der Farbwechsel der Zellen von grün zu rot ist nicht drin ... vielleicht kannst Du mir ja damit helfen?

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Not Intersect(Target, Range("A1:A1000")) Is Nothing Then
If Target = "" Then
Target = "X"
Else
Target = ""
End If
BeendeterPatient
Cancel = True
End If
End Sub
Private Sub BeendeterPatient()
Dim MyRow&
MyRow = ActiveCell.Row
If MsgBox("Teilnehmer(in) dauerhaft als beendet markieren?" & Chr(13) & Chr(10) & Chr(13) & Chr(10) & "Achtung:" & Chr(13) & Chr(10) & "- alle vorgesehenen (x) und geplanten (p) Tests werden entfernt" & Chr(13) & Chr(10) & "- erfolgte Tests bleiben erfasst", vbYesNoCancel) = vbYes Then
Application.EnableEvents = False
With Range("A" & ActiveCell.Row & ":" & "B" & ActiveCell.Row).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 255
.TintAndShade = 0
.PatternTintAndShade = 0
End With
With Range("A" & ActiveCell.Row & ":" & "I" & ActiveCell.Row).Font
.Strikethrough = True
.Italic = True
End With
With Range("J" & ActiveCell.Row & ":" & "Z" & ActiveCell.Row)  '  hier nur die range als Bezug
.Replace What:="x", Replacement:=""
.Replace What:="p", Replacement:=""
End With
Range("AA" & ActiveCell.Row & ":" & "AA" & ActiveCell.Row).Value = "Maßnahme beendet"
With Range("AA" & ActiveCell.Row & ":" & "AA" & ActiveCell.Row).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 255
.TintAndShade = 0
.PatternTintAndShade = 0
End With
Else
End If
Application.EnableEvents = True
End Sub
Wegen den Kompetenzen: ich bin hier der einzige, der sich überhaupt mit sowas befasst ... was mich reizt, ist das Problemlösen und ein später lauffähiges Ergebnis, womit viele etwas anfangen können :-) Das Forum hier ist zwar merkwürdig in der Bedienung, aber inhaltlich und vom Stil herausragend ...
LG Daniel Jäger
Anzeige
AW: Dynamischer Button in Multi-User Tabelle
10.11.2021 14:49:30
Yal
Hallo Daniel,
ich weiss nicht so ganz genau, wo die Windings gehören und Schriftfarbe gehen sollen, ich schätze mal in A.

Private Sub BeendeterPatient()
Const msg = "Teilnehmer(in) dauerhaft als beendet markieren?@@Achtung:@- alle vorgesehenen (x) und geplanten (p) Tests werden entfernt@- erfolgte Tests bleiben erfasst"
If MsgBox(Replace(msg, "@", vbCr), vbYesNoCancel)  vbYes Then Exit Sub
Application.EnableEvents = False
With Intersect(ActiveCell.EntireRow, Range("A:B")).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 255
.TintAndShade = 0
.PatternTintAndShade = 0
End With
With Intersect(ActiveCell.EntireRow, Range("A:I")).Font
.Strikethrough = True
.Italic = True
End With
With Intersect(ActiveCell.EntireRow, Range("A:A")).Font
.Color = -11489280 'Grün
.Color = -16776961 'rot
.Name = "Wingdings"
End With
With Intersect(ActiveCell.EntireRow, Range("J:Z")) '  hier nur die range als Bezug
.Replace What:="x", Replacement:=""
.Replace What:="p", Replacement:=""
End With
With Intersect(ActiveCell.EntireRow, Range("AA"))
.Value = "Maßnahme beendet"
With .Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 255
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End With
Application.EnableEvents = True
End Sub
Ich habe einiges reingebaut. Es ist nicht alles sehr sinnig, es geht eher darum zu zeigen, was möglich ist :-)
_ die Nachricht als Const und Replace um die Carriage Return (vbCr) reinzubringen
_ If .. Then Exit Sub: damit ist schon schluss, muss man nicht nach denm End If suchen
_ die Bereich als Intersect. Bringt vor allem eine bessere Übersicht
_ With in With. Ja ist möglich. Sollte man nicht übertreiben.
VG
Yal
Anzeige
AW: Dynamischer Button in Multi-User Tabelle
10.11.2021 18:01:32
Daniel
Hi Val,
Dein Hinweis war sehr gut! Ich habe jetzt eine Trickser Button-Lösung, die auch in Multiuser-Mappen läuft! Habe es via Selection.Change folgendermaßen umgesetzt:

Private Sub Worksheet_Change(ByVal Target As Range) 'wird ein neuer Patient in B eingetragen, erscheint in Wingdings eine grün hinterlegte Checkbox in A
On Error GoTo ErrExit
If Not Intersect(Range("B5:B1000"), Target) Is Nothing Then
If Target.Count = 1 Then
Application.EnableEvents = False
End If
If Target.Column  1 Then
Cells(Target.Row, 1).Interior.ColorIndex = 4
Cells(Target.Row, 1) = "x"
End If
End If
ErrExit:
Application.EnableEvents = True
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range) 'wenn Checkout nötig, rufe Makro Beenden via SelcetionChange auf Target Zelle in A auf
If Not Intersect(Target, Range("A5:A1000")) Is Nothing Then
If Target = "x" Then
Beenden
End If
Cancel = True
End If
End Sub
Private Sub Beenden()
Const msg = "Teilnehmer(in) dauerhaft als beendet markieren?@@Achtung:@- alle vorgesehenen (x) und geplanten (p) Tests werden entfernt@- erfolgte Tests bleiben erfasst"
If MsgBox(Replace(msg, "@", vbCr), vbYesNoCancel)  vbYes Then Exit Sub
Application.EnableEvents = False
With Range("A" & ActiveCell.Row & ":" & "A" & ActiveCell.Row)
.Value = "o"
End With
With Intersect(ActiveCell.EntireRow, Range("A:B")).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 255
.TintAndShade = 0
.PatternTintAndShade = 0
End With
With Intersect(ActiveCell.EntireRow, Range("B:I")).Font
.Strikethrough = True
.Italic = True
End With
With Intersect(ActiveCell.EntireRow, Range("J:Z"))
.Replace What:="x", Replacement:=""
.Replace What:="p", Replacement:=""
End With
With Range("AA" & ActiveCell.Row & ":" & "AA" & ActiveCell.Row).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 255
.TintAndShade = 0
.PatternTintAndShade = 0
End With
With Range("AA" & ActiveCell.Row & ":" & "AA" & ActiveCell.Row)
.Value = "Maßnahme beendet"
End With
Application.EnableEvents = True
End Sub
Für einen Psychologen mit VBA-Grundlagen nicht übel, oder *g*
Danke für Eure tolle Hilfe wieder einmal ...
Daniel Jäger
Anzeige
AW: Dynamischer Button in Multi-User Tabelle
10.11.2021 18:27:38
Daniel
... mmh, ok - einen Fehler gibt es doch: man kann nicht mehr mit Spalte A markieren/selektieren (Laufzeitfehler 13 - Typen unverträglich). Muss man aussparen oder gibt es da einen Trick, um das zu beheben?
AW: Dynamischer Button in Multi-User Tabelle
11.11.2021 14:08:35
Yal
Hallo Daniel,
ja, sehr gut!
Kannst Du sagen, wo diese Fehler auftaucht?
Achte ebenfalls auf eine saubere Identation. Es macht den Code leichter zu lesen.
VG
Yal
AW: Dynamischer Button in Multi-User Tabelle
11.11.2021 14:47:03
Daniel
Hi Yal,
keine Ahnung ... passiert immer, sobald Zellen in Spalte A in irgendeiner Form mit anderen Zellen gemeinsam markiert werden. Datei liegt hier: https://www.herber.de/bbs/user/149087.xlsm (kleine Fassung)
LG Daniel Jäger
Anzeige
AW: Dynamischer Button in Multi-User Tabelle
11.11.2021 15:11:02
Daniel
Hi
viele Bedenken nicht - wenn sie SelectionChange- oder Change-Eventmakros schreiben - dass der Anwender auch mal mehrere Zellen gleichzeitig selektieren oder ändern kann, sondern gehen immer von der Einzelzelle aus, das ist aber nicht realistisch, es passiert, wie du festgestellt hast, häufiger, dass man mehrere Zellen selektiert.
Dann umfasst die Variable TARGET (also die gänderteten Zellen) nicht nur eine Zelle, sondern mehrere.
Wenn man dann Target bzw Target.Value verwendet, muss man bedenken, dass dies dann keinen Einzelwert ergibt, sondern ein Array und dann Programmzeilen wie Target = "x" nicht mehr funktionieren, weil man ein Array nicht mit einem Einzelwert vergleichen kann.
je nach dem was passieren soll, gibts da verschiedene Lösungsansätze.
Wenn man davon ausgeht, dass der Anwender immer nur einen einzigen "Kunden" gleichzeitig bearbeiten soll, könnte man einfach das Makro nur dann ausführen, wenn eine einzige Zelle markiert ist, hierzu zählt man die Zellen, die markiert wurden mit COUNTLARGE

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.CountLarge = 1 then
If Not Intersect(Target, Range("A5:A1000")) Is Nothing Then
If Target = "x" Then
Beenden
End If
Cancel = True
End If
End If
End Sub
ich persönlich würde an dieser Stelle nicht das SelectionChange-Event-Makro verwenden, um diese Aktion auszulösen, sondern das BeforeDoubleClick-Event.
Ein Doppelklick ist auf jeden Fall verbindlicher und passiert nicht so schnell zufällig und beim Doppelklick gibt es automatisch nur eine einzige Zelle die man doppelt klicken kann, von daher entsteht das Problem gar nicht.
Gruß Daniel
Anzeige
AW: Dynamischer Button in Multi-User Tabelle
11.11.2021 17:54:35
Yal
Hallo Daniel (J),
wenn ich die Antwort von Daniel berücksichtige, müssen wir die Selektion pro Zeile nachgehen:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim Z As Range
Set Liste = New Collection
If Not Intersect(Target, Range("A5:A1000")) Is Nothing Then
'        For Each Z In Target.Cells         |
'            Z.EntireRow.Range("A1") = "x"  | nutzlos, da anschliessend auf "o" gesetzt
'        Next                               |
Beendung_einsetzen (Target)
Cancel = True
End If
End Sub
Private Sub Beendung_einsetzen(Target As Range)
Dim Z As Range
Dim S As Range
Const msg = "Teilnehmer(in) dauerhaft als beendet markieren?@@Achtung:@- alle vorgesehenen (x) und geplanten (p) Tests werden entfernt@- erfolgte Tests bleiben erfasst"
If MsgBox(Replace(msg, "@", vbCr), vbYesNoCancel)  vbYes Then Exit Sub
Application.EnableEvents = False
Application.ScreenUpdating = False
For Each Z In Target.Cells
With Z.EntireRow
.Range("A1").Value = "o"
.Range("AA1").Value = "Maßnahme beendet"
For Each S In .Range("J1:Z1").Cells
S.Replace What:="x", Replacement:=""
S.Replace What:="p", Replacement:=""
Next
With .Range("A1:B1", "AA1").Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 255
.TintAndShade = 0
.PatternTintAndShade = 0
End With
With .Range("B1:I1").Font
.Strikethrough = True
.Italic = True
End With
End With
Next
Application.EnableEvents = True
Application.ScreenUpdating = False
End Sub
Nachdem aus einer Zelle "EntireRow" gezeigt wird, ist die erste Zelle diese Zeile A1. Daher kann man mit relativen Adresse arbeiten.
Einige Kürzungen sind auch möglich.
VG
Yal
Anzeige
AW: Dynamischer Button in Multi-User Tabelle
11.11.2021 22:34:48
Daniel
Guten Abend,
die CountLarge Variante von Daniel habe ich mit DoubleClick Ereignis probiert - die geht auf Anhieb; entsprechend meckert er auch nicht bei Markierungen.
Deine interessante Idee Val gibt leider einen Fehler aus "Argument ist nicht optimal" (Kompilierung). Ich kann also nicht sagen, ob es eine Verbesserung bringen würde. Was bedeutet der Befehl Set Liste = New Collection? Ist das die Mehrfachselektion mit Spalte A Zellen? In Zeile 1 sind vor allem Status Meldungen hinterlegt; die Patientendaten gehen erst ab A5 los ... oder ist das nur ein interner Anker für relative Adressierungen?
LG Daniel Jäger
Oops
12.11.2021 12:43:00
Yal
Hallo Daniel,
Ich habe eine erste Version gebaut, wo ich die selektierte Zeilen in einer Auflistung sammeln (="Collection"), dann aber wieder abgespeckt, da "Target" auch eine Auflistung der gewählte Zellen darstellt. Beim Aufräumen habe ich "Set Liste = New Collection" übersehen. Weg damit.
Wenn Du von einem Abbruch mit Fehler sprichst, muss Du auch sagen wo.
Lege eine Haltepunkt auf der Zeile "If Not Intersect ...": Cursor auf Zeile legen, F9 Drucken.
Der Code-Durchlauf wird danch auf diese Zeile stehen bleiben (Haltepunkt), dann gehst Du weiter im Schrittmodus (F8) und siehst, wo der Fehler entsteht.
2 Hilfsmitteln musst Du auch kennenlernen:
_ Während den Schritt-Durchlauf, öffne das Lokalfenster (Ansicht, Lokalfenster). Da siehst Du alle aktuelle Variablen und deren Inhalt. Du erfährst auch viel über die Excel-Objekte und Ihre Struktur
_ in deinem Fall, weil hier wenige eigene Variablen verwendet werden, ist das Lokalfenster verwirrend, weil zu viel, sind Überwachungsausdrücke besser. Rechtsklick auf eine Variable Wie z.B. Z und "Überwachung hinzufügen...". Wenn es ein Ojekt ist, kann man gezielt eine Eigenschaft überwachen: Z.Address.
VG
Yal
AW: Oops
13.11.2021 09:39:26
Daniel
Hi Val, (und Daniel auch)
Danke für Deine/Eure Mühe. Ich kenne in der tat noch nicht alle Helferlein im VBA Universum. Kurze Anmerkung zum Code. Ich habe das BDC-Event doch wieder rausgenommen, da es weniger intuitiv ist. Mit dieser Abwandlung Eurer beiden Hinweise klappt jetzt alles:
- Markieren beliebiger Zellbereiche inkl. Zellen aus A ohne Laufzeitfehler
- Keine Sub, wenn Beendigung schon erfolgt/angezeigt ist (vorher hat das Event immer ausgelöst)

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.CountLarge = 1 Then
If Not Intersect(Target, Range("A5:A1000")) Is Nothing Then
If Target = "o" Then Exit Sub
If Target = "" Then Exit Sub
Beenden
Cancel = True
End If
End If
End Sub
Danke für die tolle Hilfe!
Mir schwebt eine neue Funktion vor, die ich aber an anderer Stelle im Forum platziere (markierten Tabellenbereich an Mitarbeiter als Email verschicken, die im markierten Zellbereich enthalten sind ...)
Liebe Grüße
Daniel Jäger

Links zu Excel-Dialogen

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige