Avatar billede macho Praktikant
29. november 2005 - 09:41 Der er 16 kommentarer og
1 løsning

Farvelægning af celler - igen, igen.

Jeg vil meget gerne have erstattet en betinget formatering med VB-kode, da den betingede formatering sløver mit ark gevaldigt.
Det drejer sig om farvning af helligdag - igen, igen.

Nedenstående VB-kode har jeg fra et andet regneark:

  På selve arket:

********** 
 
Option Explicit

Private Const msRNG_START As String = "Start"

Private Sub Worksheet_Change(ByVal Target As Range)
    'Flemming Dahl, November 2005, fvd@smartoffice.dk
    If Not Intersect(Target, Range(msRNG_START)) Is Nothing Then
        ColorWeekendsAndHolidaies Me.Name
        Application.Calculate
    End If
End Sub

***********

og i et modul:

***********

Option Explicit

Function ErHelligdag(ByVal TestDato As Long, _
    Optional ByVal InclLørdage As Boolean = True, _
    Optional ByVal InclSøndage As Boolean = True) As Boolean
   
    Dim InputYear As Integer, PD As Long, OK As Boolean
    If TestDato <= 0 Then TestDato = Date
    InputYear = Year(TestDato)
    PD = Påskedag(InputYear)
    OK = True
    Select Case TestDato
        Case DateSerial(InputYear, 1, 1) ' Nytårsdag
        Case PD - 7    ' Palmesøndag
        Case PD - 3    ' Skærtorsdag
        Case PD - 2    ' Langfredag
        Case PD        ' Påskedag
        Case PD + 1    ' 2. påskedag
        Case PD + 26    ' St. Bededag
        Case PD + 39    ' Kristi Himmelfartsdag
        Case PD + 49    ' Pinsedag
        Case PD + 50    ' 2. Pinsedag
        Case DateSerial(InputYear, 12, 25) ' Juledag
        Case DateSerial(InputYear, 12, 26) ' 2. Juledag
        Case DateSerial(InputYear, 12, 31) ' Nytårsaftensdag
        Case Else
            OK = False
            If InclLørdage Then
                If Weekday(TestDato, vbMonday) = 6 Then
                    OK = True
                End If
            End If
            If InclSøndage Then
                If Weekday(TestDato, vbMonday) = 7 Then
                    OK = True
                End If
            End If
    End Select
    ErHelligdag = OK
End Function

Function Påskedag(InputYear As Integer) As Long
    Dim d As Integer
    d = (((255 - 11 * (InputYear Mod 19)) - 21) Mod 30) + 21
    Påskedag = DateSerial(InputYear, 3, 1) + d + (d > 48) + 6 - _
        ((InputYear + InputYear \ 4 + d + (d > 48) + 1) Mod 7)
End Function

Function UgeNr(Dato)
    UgeNr = Format(Dato, "ww", vbMonday, vbFirstFourDays)
End Function

Public Function ColoredCellsCount(rCountArea As Range, rCountColor As Range) As Double
    'Flemming Dahl, Januar 2002, fvd@smartoffice.dk
    Application.Volatile
    Dim dRetVal As Double
    Dim rCell As Range
    Dim iColor As Integer
    For Each rCell In rCountArea
        If rCell.Interior.ColorIndex = rCountColor.Interior.ColorIndex Then
            dRetVal = dRetVal + 1
        End If
    Next rCell
    ColoredCellsCount = dRetVal
    ' Clean up
    Set rCell = Nothing
End Function

Public Sub ColorWeekendsAndHolidaies(ByVal sSheetName As String)
    'Flemming Dahl, November 2005, fvd@smartoffice.dk
    ' Erstatning for betinget formatering
    Const sRNG_HEADER As String = "Header"
    Dim rCell As Range
    Dim rCurReg As Range
    Dim lCol As Long
    Dim bBlank As Boolean
   
    ' Find CurrentRegion med udgangspunkt i header rækken (6)
    Set rCurReg = Worksheets(sSheetName).Range(sRNG_HEADER).CurrentRegion
    ' Fjern header rækken fra rCurReg
    Set rCurReg = rCurReg.Offset(1, 0).Resize(rCurReg.Rows.Count - 1)
   
    For Each rCell In rCurReg.Columns(3).Cells
        bBlank = False
        If Not Trim$(rCell.Value) = "" Then
            If ErHelligdag(rCell.Value) Then
                ' Helligdag
                For lCol = -1 To rCurReg.Columns.Count - 4
                    rCell.Offset(0, lCol).Interior.ColorIndex = 15
                Next lCol
            Else
                bBlank = True
            End If
        Else
            bBlank = True
        End If
       
        If bBlank Then
            ' Arbejdsdag
            For lCol = -1 To rCurReg.Columns.Count - 4
                rCell.Offset(0, lCol).Interior.ColorIndex = xlNone
            Next lCol
        End If
    Next rCell
End Sub

********************

Ovenstående passer til en kalender (se dette spørgsmål: http://www.exp.dk/spm/667095 ) men i mit nye skema, så har jeg mine datoer i en række, i stedet for en kolonne. Datoerne strækker sig fra B2:AF2.

Det jeg gerne vil have i mit nye skema, er muligheden for at farvelægge helligdage/lørdage/søndage i 6 celler UNDER en dato (altså samme kolonne som datoen, f.eks. B3:B8). Faktisk skal det ske flere steder på arket, men det er altid i samme kolonne og altid seks celler under datoen, som skal farvelægges. Selve datoen skal ikke farvelægges.
Som sagt, så gør koden herover det, at den farvelægger selve datoen og så seks celler til højre for datoen (i samme række).

Ups... mon det er til at forstå?
Avatar billede kabbak Professor
29. november 2005 - 09:52 #1
Function ErHelligdag(ByVal TestDato As Long, _
    Optional ByVal InclLørdage As Boolean = True, _
    Optional ByVal InclSøndage As Boolean = True) As Boolean
 
    Dim InputYear As Integer, PD As Long, OK As Boolean
    If TestDato <= 0 Then TestDato = Date
    InputYear = Year(TestDato)
    PD = Påskedag(InputYear)
    OK = True
    Select Case TestDato
        Case DateSerial(InputYear, 1, 1) ' Nytårsdag
        Case PD - 7    ' Palmesøndag
        Case PD - 3    ' Skærtorsdag
        Case PD - 2    ' Langfredag
        Case PD        ' Påskedag
        Case PD + 1    ' 2. påskedag
        Case PD + 26    ' St. Bededag
        Case PD + 39    ' Kristi Himmelfartsdag
        Case PD + 49    ' Pinsedag
        Case PD + 50    ' 2. Pinsedag
        Case DateSerial(InputYear, 12, 25) ' Juledag
        Case DateSerial(InputYear, 12, 26) ' 2. Juledag
        Case DateSerial(InputYear, 12, 31) ' Nytårsaftensdag
        Case Else
            OK = False
            If InclLørdage Then
                If Weekday(TestDato, vbMonday) = 6 Then
                    OK = True
                End If
            End If
            If InclSøndage Then
                If Weekday(TestDato, vbMonday) = 7 Then
                    OK = True
                End If
            End If
    End Select
    ErHelligdag = OK
End Function

Function Påskedag(InputYear As Integer) As Long
    Dim d As Integer
    d = (((255 - 11 * (InputYear Mod 19)) - 21) Mod 30) + 21
    Påskedag = DateSerial(InputYear, 3, 1) + d + (d > 48) + 6 - _
        ((InputYear + InputYear \ 4 + d + (d > 48) + 1) Mod 7)
End Function


Betinget formatering, mener jeg er ok

Marker cellerne B3 til AF8
Formater > Betinget formatering
Formlen er

=ErHelligdag(B$2)
Avatar billede kabbak Professor
29. november 2005 - 09:53 #2
husk at sætte formatet
Avatar billede macho Praktikant
29. november 2005 - 15:01 #3
Det du'r ikke med betinget formatering, da jeg så ikke kan bruge funktionen ColoredCellsCount...?
Avatar billede kabbak Professor
29. november 2005 - 22:00 #4
Public Sub MarkerHelligdage()
For Each c In Range(" B2:AF2").Cells
If ErHelligdag(c) Then
Range(Cells(3, c.Column), Cells(8, c.Column)).Interior.ColorIndex = 6
Else
Range(Cells(3, c.Column), Cells(8, c.Column)).Interior.ColorIndex = xlNone
End If
Next
End Sub


Function ErHelligdag(ByVal TestDato As Long, _
    Optional ByVal InclLørdage As Boolean = True, _
    Optional ByVal InclSøndage As Boolean = True) As Boolean
 
    Dim InputYear As Integer, PD As Long, OK As Boolean
    If TestDato <= 0 Then TestDato = Date
    InputYear = Year(TestDato)
    PD = Påskedag(InputYear)
    OK = True
    Select Case TestDato
        Case DateSerial(InputYear, 1, 1) ' Nytårsdag
        Case PD - 7    ' Palmesøndag
        Case PD - 3    ' Skærtorsdag
        Case PD - 2    ' Langfredag
        Case PD        ' Påskedag
        Case PD + 1    ' 2. påskedag
        Case PD + 26    ' St. Bededag
        Case PD + 39    ' Kristi Himmelfartsdag
        Case PD + 49    ' Pinsedag
        Case PD + 50    ' 2. Pinsedag
        Case DateSerial(InputYear, 12, 25) ' Juledag
        Case DateSerial(InputYear, 12, 26) ' 2. Juledag
        Case DateSerial(InputYear, 12, 31) ' Nytårsaftensdag
        Case Else
            OK = False
            If InclLørdage Then
                If Weekday(TestDato, vbMonday) = 6 Then
                    OK = True
                End If
            End If
            If InclSøndage Then
                If Weekday(TestDato, vbMonday) = 7 Then
                    OK = True
                End If
            End If
    End Select
    ErHelligdag = OK
End Function

Function Påskedag(InputYear As Integer) As Long
    Dim d As Integer
    d = (((255 - 11 * (InputYear Mod 19)) - 21) Mod 30) + 21
    Påskedag = DateSerial(InputYear, 3, 1) + d + (d > 48) + 6 - _
        ((InputYear + InputYear \ 4 + d + (d > 48) + 1) Mod 7)
End Function
Avatar billede macho Praktikant
29. november 2005 - 22:51 #5
Hhmmm... der sker ikke noget, når jeg indtaster i min dato-start-celle. Beregningerne til kalenderen sker, når jeg har indtastet dato i "Start"-celle. Skal der være noget kode på selve arket også, for at få det til at virke?
Avatar billede kabbak Professor
29. november 2005 - 22:57 #6
sæt denne i arkmodulet

Private Sub Worksheet_Change(ByVal Target As Range)
      If Not Intersect(Target, Range(" B2:AF2")) Is Nothing Then
If ErHelligdag(Target) Then
Range(Cells(3, Target.Column), Cells(8, Target.Column)).Interior.ColorIndex = 6
Else
Range(Cells(3, Target.Column), Cells(8, Target.Column)).Interior.ColorIndex = xlNone
End If
    End If
End Sub




de andre funktioner skal værei et modul

Function ErHelligdag(ByVal TestDato As Long, _
    Optional ByVal InclLørdage As Boolean = True, _
    Optional ByVal InclSøndage As Boolean = True) As Boolean
 
    Dim InputYear As Integer, PD As Long, OK As Boolean
    If TestDato <= 0 Then TestDato = Date
    InputYear = Year(TestDato)
    PD = Påskedag(InputYear)
    OK = True
    Select Case TestDato
        Case DateSerial(InputYear, 1, 1) ' Nytårsdag
        Case PD - 7    ' Palmesøndag
        Case PD - 3    ' Skærtorsdag
        Case PD - 2    ' Langfredag
        Case PD        ' Påskedag
        Case PD + 1    ' 2. påskedag
        Case PD + 26    ' St. Bededag
        Case PD + 39    ' Kristi Himmelfartsdag
        Case PD + 49    ' Pinsedag
        Case PD + 50    ' 2. Pinsedag
        Case DateSerial(InputYear, 12, 25) ' Juledag
        Case DateSerial(InputYear, 12, 26) ' 2. Juledag
        Case DateSerial(InputYear, 12, 31) ' Nytårsaftensdag
        Case Else
            OK = False
            If InclLørdage Then
                If Weekday(TestDato, vbMonday) = 6 Then
                    OK = True
                End If
            End If
            If InclSøndage Then
                If Weekday(TestDato, vbMonday) = 7 Then
                    OK = True
                End If
            End If
    End Select
    ErHelligdag = OK
End Function

Function Påskedag(InputYear As Integer) As Long
    Dim d As Integer
    d = (((255 - 11 * (InputYear Mod 19)) - 21) Mod 30) + 21
    Påskedag = DateSerial(InputYear, 3, 1) + d + (d > 48) + 6 - _
        ((InputYear + InputYear \ 4 + d + (d > 48) + 1) Mod 7)
End Function
Avatar billede macho Praktikant
29. november 2005 - 23:09 #7
Nu kan jeg få cellerne til at skifte farve, men kun hvis jeg indtaster datoen direkte i dato-cellen. Som sagt, så bliver kalenderen genereret ud fra et "Start"-felt, som jeg har i AJ2 og heri indtaster jeg f.eks. januar 2006. I kalenderen bliver dato-cellerne regnet ud med denne funktion:
B2:
=HVIS(AJ2<>"";HVIS(MÅNED(AJ2+1)=MÅNED($AJ$2);AJ2;"");"")
C2:
=HVIS(AJ2<>"";HVIS(MÅNED(AJ2+1)=MÅNED($AJ$2);AJ2+1;"");"")
D2:
=HVIS(C2<>"";HVIS(MÅNED(C2+1)=MÅNED($AJ$2);C2+1;"");"")
E2:
=HVIS(D2<>"";HVIS(MÅNED(D2+1)=MÅNED($AJ$2);D2+1;"");"")
F2:
=HVIS(E2<>"";HVIS(MÅNED(E2+1)=MÅNED($AJ$2);E2+1;"");"")

osv... op til AF2.
Den generering af kalenderen virker fint, men den farvelægges altså ikke i helligdage og lør-/søndage?
Avatar billede kabbak Professor
29. november 2005 - 23:14 #8
hvad med at køre makroen som jeg viste 22:00:52

den tjekker

du skal bare køre den når det med datoerne er på plads
Avatar billede macho Praktikant
29. november 2005 - 23:42 #9
Uha, det er hårdt det her. Håber ikke, at jeg er for tung at danse med!!

Nu virker det jo med det du lavede 22:00:52 - det var jo mig selv, som ikke havde gennemskuet makroen!

Kan jeg tilføje farver til flere celler. Jeg har samme datorække i B10:AF10 og skal altså have farvet i rækkerne 11 til 16 (og flere endnu). Er det nemt at ændre i makroen?
Avatar billede kabbak Professor
29. november 2005 - 23:46 #10
Public Sub MarkerHelligdage()
For Each c In Range(" B2:AF2").Cells
If ErHelligdag(c) Then
Range(Cells(3, c.Column), Cells(8, c.Column)).Interior.ColorIndex = 6
Range(Cells(11, c.Column), Cells(16, c.Column)).Interior.ColorIndex = 6
Else
Range(Cells(3, c.Column), Cells(8, c.Column)).Interior.ColorIndex = xlNone
Range(Cells(11, c.Column), Cells(16, c.Column)).Interior.ColorIndex = xlNone
End If
Next
End Sub

bare sæt flere ind, når det er de samme datorer som i række 2
Avatar billede macho Praktikant
29. november 2005 - 23:59 #11
Perfekt, kabbak. Så er det vist tid for points...
Mange tak for hjælpen!
Avatar billede kabbak Professor
29. november 2005 - 23:59 #12
et svar ;-))
Avatar billede macho Praktikant
30. november 2005 - 00:11 #13
Du for points, men jeg er netop stødt ind i et problem:
Hvis jeg har en måned, hvor der er færre end 31 dage, så får jeg en advarsel VB-advarsel "type mismatch" og den laver nogen gange cellerne farvede...?
Avatar billede kabbak Professor
30. november 2005 - 00:14 #14
Public Sub MarkerHelligdage()
For Each c In Range(" B2:AF2").Cells
If IsDate(c) Then
If ErHelligdag(c) Then
Range(Cells(3, c.Column), Cells(8, c.Column)).Interior.ColorIndex = 6
Range(Cells(11, c.Column), Cells(16, c.Column)).Interior.ColorIndex = 6
Else
Range(Cells(3, c.Column), Cells(8, c.Column)).Interior.ColorIndex = xlNone
Range(Cells(11, c.Column), Cells(16, c.Column)).Interior.ColorIndex = xlNone
End If
End If
Next

End Sub
Avatar billede macho Praktikant
30. november 2005 - 00:29 #15
Ingen fejlmeddelelser nu, men er det muligt at tilføje noget til makroen, således at felterne bliver ryddet for farve før den lægger den nye på?
Hvis ikke, så vil der nogle gange være markeret week-end i slutningen af en måned, selv om datoen ikke eksisterer (rester fra tidligere)
Avatar billede kabbak Professor
30. november 2005 - 00:32 #16
Public Sub MarkerHelligdage()
For Each c In Range(" B2:AF2").Cells
If IsDate(c) Then
If ErHelligdag(c) Then
Range(Cells(3, c.Column), Cells(8, c.Column)).Interior.ColorIndex = 6
Range(Cells(11, c.Column), Cells(16, c.Column)).Interior.ColorIndex = 6
Else
Range(Cells(3, c.Column), Cells(8, c.Column)).Interior.ColorIndex = xlNone
Range(Cells(11, c.Column), Cells(16, c.Column)).Interior.ColorIndex = xlNone
End If
Else
Range(Cells(3, c.Column), Cells(8, c.Column)).Interior.ColorIndex = xlNone
Range(Cells(11, c.Column), Cells(16, c.Column)).Interior.ColorIndex = xlNone
End If
Next

End Sub
Avatar billede macho Praktikant
30. november 2005 - 00:37 #17
Fantistisk - så er vi vist også færdige med den her ;-)

Takker endnu en gang for hjælpen... !
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Excel kurser for alle niveauer og behov – find det kursus, der passer til dig

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester