PDA

Vollständige Version anzeigen : Selection.Columns.Count mit nicht zusammenhängendem Bereich


Feng Bo
30.08.2017, 10:15
Hallo zusammen,

für eine Urlaubsplanung möchte ich, dass ein Hinweis erscheint, wenn zu viel Urlaub beantragt wurde.
Dies berechnet sich dann "einfach" nach Resturlaub ./. Bereits beantragt ./. Anzahl markierter Zellen:

Sub Antrag()
If Cells(ActiveCell.Row, 9).Value - Selection.Columns.Count - Cells(ActiveCell.Row, 7).Value < 0 Then
If MsgBox("Sie haben noch " & Cells(ActiveCell.Row, 9).Value & " Tage Resturlaub zur Verfügung und damit " & (Cells(ActiveCell.Row, 9).Value - (Selection.Columns.Count + Cells(ActiveCell.Row, 7).Value)) * -1 & " Tag(e) zu viel beantragt. " & vbCr & vbCr & "Trotzdem fortfahren?", vbYesNo) = vbNo Then Exit Sub
End If

ActiveSheet.Unprotect
With Selection
.Font.Name = "Wingdings"
.Value = "¹"
End With

ActiveSheet.Protect

End Sub

Nun habe ich das Problem:
Ich markiere z. B. Montag bis Freitag
- Bsp: AA6:AE6
und mit STRG fünf weitere Zellen in der Folgewoche:
- Bsp: AG6:AK6

Es sind also 10 markierte Zellen. Excel erkennt aber nur 5 davon, da die anderen fünf Zellen durch nicht markierte Zellen abgetrennt sind.

Kann mir bitte jemand helfen? :)

Vielen Dank!

aloys78
30.08.2017, 11:01
Hallo Feng,
Excel erkennt aber nur 5 davon ...
Nach meiner Kenntnis werden für diesen Zweck nur die zuerst markierten Zellen berücksichtigt.

Wenn Du mit markieren arbeiten willst, dann fällt mir im Moment nur folgender Lösungsansatz ein:
- Bereiche nacheinander ohne StRG-Taste markieren,
- per Worksheet_SelectionChange-Ereignis werden diese Bereiche schritthaltend zB gelb eingefärbt,
- zum Abschluß drückst Du einen Button: die gelb markierten Spaltenbereiche werden verarbeitet, dann wird die Farbe wieder entfernt.

Gruß
Aloys

Jonas0806
30.08.2017, 11:04
Hallo auch von mir,

Excel arbeitet hier mit Areas. Prüfe also, ob Du mehr als eine Area hast und itteriere dann entsprechend.

Dim i As Long
Dim cols As Integer: cols = 0

With Selection
If .Areas.Count > 1 Then
For i = 1 To .Areas.Count
cols = cols + .Areas(i).Columns.Count
Next i
Else
cols = .Columns.Count
End If
End With

Debug.Print cols

Feng Bo
31.08.2017, 09:41
Hallo, vielen Dank erstmal für das Feedback und den Code. Wo verwurschtel ich den aber nun?

Das ist mein aktueller Code:
Sub Antrag()

If Cells(ActiveCell.Row, 4).Value - Selection.Columns.Count - Cells(ActiveCell.Row, 2).Value < 0 Then
If MsgBox("Sie haben noch " & Cells(ActiveCell.Row, 4).Value & " Tage Resturlaub zur Verfügung und damit " & (Cells(ActiveCell.Row, 4).Value - (Selection.Columns.Count + Cells(ActiveCell.Row, 2).Value)) * -1 & " Tag(e) zu viel beantragt. " & vbCr & vbCr & "Trotzdem fortfahren?", vbYesNo) = vbNo Then Exit Sub
End If

ActiveSheet.Unprotect Password:="xxx"
With Selection
.Font.Name = "Wingdings"
.Value = "¹"
End With

ActiveSheet.Protect Password:="xxx"

End Sub

In Spalte D steht der Resturlaub, bereits beantragter (aber noch nicht genehmigter) Urlaub in Spalte B. Der muss auch berücksichtigt sein.
Also z. B.
8 Tage Resturlaub
5 Tage bereits beantragt
=de facto noch 3 Tage Rest (nach Genehmigung)

Wenn ich nun 2 mal 5 Zellen markiere muss die Meldung kommen, dass 7 Tage zu viel beantragt wurden. Die aktuelle Meldung geht aber nur von 2 Tagen zu viel aus, weil die Areas nicht berücksichtigt sind.

Wo muss der Code nun hin?
Vielen Dank nochmals für die Mühe! Grüße

aloys78
31.08.2017, 15:19
Hallo Feng,

mein Vorschlag, der auf dem Code von Jonas aufbaut.
Option Explicit

Sub Antrag()
Dim nCol As Long, a As Long, n As Long, r As Long
With Selection
For a = 1 To .Areas.Count
nCol = nCol + .Areas(a).Columns.Count
Next a
r = .Row
End With

With ActiveSheet
n = .Range("D" & r) - .Range("B" & r) - nCol
If n < 0 Then
If MsgBox("Sie haben noch " & .Range("D" & r) & " Tage Resturlaub zur Verfügung und damit " _
& n * (-1) & " Tag(e) zu viel beantragt. " _
& vbCr & vbCr & "Trotzdem fortfahren?", vbYesNo) = vbNo Then
Exit Sub
End If
End If

.Unprotect Password:="xxx"
End With

With Selection
For a = 1 To .Areas.Count
.Areas(a).Font.Name = "Wingdings"
.Areas(a).Value = "¹"
Next a
End With
ActiveSheet.Protect Password:="xxx"
End Sub

Gruß
Aloys

lupo1
31.08.2017, 15:28
Ich tät das ja mit bedF oder mit DÜ lösen ... nichtzusammenhängende Bereiche auswerten: Wie doof ist das denn?

RPP63neu
31.08.2017, 15:35
Ich würde den ganzen Blödsinn sein lassen und mir Urlaubsanträge zur Prüfung vorlegen lassen.
(und ja! nach Prüfung manuell eintragen)
Ist zwar "Altland" (Merkel reverse), funktioniert aber immer noch.

[Und bis der Quanten-Computer kommt, verlasse ich mich immer noch auf so etwas wie (Vorsicht! Fremdwort) Erfahrung!]

Two Cents,
Ralf

Feng Bo
05.09.2017, 09:36
Hm bis dahin erstmal herzlichen Dank für eure Mühe! Ich denke ihr habt Recht, dass das Unsinn ist.
Anders gefragt:

In Spalte B steht "bereits beantragter Urlaub". Meistens Null, kann aber auch höher sein. Ist es möglich, bevor das ganze Makro startet, sich den Wert aus Spalte B zu merken und mit dem neuen Wert zu vergleichen?
Es funktioniert so:
In Spalte B heißt es ZÄHLENWENN... Zellwert = 1
Nun beantrage ich neuen Urlaub, auch diese Zellen erhalten Zellwert 1. BEVOR dies nun berücksichtigt wird, soll Excel den alten Wert aus Spalte B von dem neuen Wert, der ja dann höher ist, abziehen.

Würdet ihr bitte nochmals helfen? :)

Vielen Dank!