VGnet.dk - Function eller Sub?

Spørgsmålet belyses til sidst i teksten, men først nogle mere generelle overvejelser.

Pro & contra VBA

Styrken i VBA/Excel er bl.a.

  • den direkte kobling mellem data og programkode — i en vis forstand ”objektorienteret pro-grammering i 2. potens”
  • en høj grad af smidighed — f.eks. den fikse datatype Variant, som kan rumme alle andre typer

Svagheden er bl.a.

  • at VBA ikke er et ægte objektorienteret sprog
  • at VBA er noget langsommere end rigtige programmeringssprog
  • at man selv skal skrive eller finde specielle faciliteter

Hvornår bruger man VBA?

Regneark til rene Excel-brugere laves bedst i ren Excel-formelgymnastik. VBA til Excel bruger jeg mest til

  • funktioner, der ikke findes i Excel
  • automatiserede rutineopgaver (makrokørsel)
  • kompliceret behandling af store datamængder

Automatiserede rutineopgaver kan i nogle tilfælde klares med at indspille en makro og rette den til. Egentlig databehandling kræver rutiner til

  • indfangning af data og hjælpedata, f.eks. fra regnearkene til et array
  • behandling af data, typisk i et array i hukommelsen
  • udskrivning af data, f.eks. i form af et dump fra et array til et (nyt) regneark

Tip: Kommunikation mellem Excel og VBA kan være enormt langsom, specielt ved output til Excel. Der findes dog metoder til at skrive store arrays hurtigt til Excel. VBA har en fornuftig grad af brugerstyret fejlhåndtering. Et brugervenligt program bør forudse fejlene og forskåne brugeren for dem. VBA understøtter temmelig avancerede formularer. Hvis man skal opnå en høj grad af brugervenlighed, kan man overveje at sovse det hele ind i formularstyring.

Programstruktur

VBA har gode muligheder for at fastlægge scope (global/lokal) for variable.

VBA har to typer af procedurer: funktioner (Function) og subrutiner (Sub). De kan ikke det samme.

Sub:

  • En Sub kan hente data fra argumenter eller fra Excel og skrive til Excel.
  • En Sub kan ikke anvendes til kald ude fra en Excel-celle.
  • En Sub kan ikke returnere en eksplicit værdi.
  • En Sub kan udmærket returnere en implicit værdi i form af en ændret værdi af et af sine argumenter, hvis det er kaldt som pointer (kaldet ByRef, "by reference").

Function:

  • En Function kan hente data fra argumenter eller fra Excel.
  • En Function kan anvendes til kald ude fra en Excel-celle, men hvis funktionen er kaldt eller styret af et kald fra Excel, kan funktionen ikke skrive til Excel eller i det hele taget manipulere Excel.
  • Hvis funktionen kun er kaldt fra VBA, kan den godt manipulere Excel og opfører sig næsten ligesom en Sub.
  • En Function returnerer en værdi, men
    • returværdien behøver ikke være tildelt en meningsfyldt værdi.
    • returværdien kan være enten en enkelt værdi eller f.eks. et array af forskellige data.
    • funktionen kan godt kaldes fra VBA som en Sub og uden at man tildeler dens returværdi til en variabel eller på anden vis bruger den til noget.
  • En Function kan også ligesom en Sub returnere en implicit værdi i form af en ændret værdi af et af sine argumenter, hvis det er kaldt som pointer (kaldet ByRef, "by reference").

VBA og WSH

Hvis man skal omskrive VBA-rutiner til WSH, skal man være opmærksom på, at WSH har nogle indviklede regler for, hvad der går an og ikke går an. Her kommer en oversigt, illustreret ved eksempler.

Sub Rutine1(x)
End Sub
Sub Rutine2(a, b)
End Sub
Function Funktion(y)
End Function
z = 123
  • Sub
    • Ét argument
      • ByRef
      Rutine1 z              ' tilladt; håndterer z "by reference"
      Call Rutine1(z)        ' tilladt; håndterer z "by reference"
      • ByVal
        Rutine1(z)             ' tilladt; håndterer z "by value"
        Call Rutine1((z))      ' tilladt; håndterer z "by value"
    • Flere argumenter
      • ByRef
        Rutine2 z, z           ' tilladt; håndterer z "by reference"
        Rutine2 (z), (z)       ' tilladt; håndterer z "by reference"
        Call Rutine2(z, z)     ' tilladt; håndterer z "by reference"
      • ByVal
        Call Rutine2((z), (z)) ' tilladt; håndterer z "by value"
      • Ubrugelig
        'Rutine2(z,z)          ' ubrugelig; kan ikke bruge parenteser
        'Call Rutine2 z, z     ' ubrugelig; parenteser kræves
  • Function
    • ByRef
      n = Funktion(z)         ' tilladt; håndterer z "by reference"
      n = Funktion((z))       ' tilladt; håndterer z "by reference"
      Funktion z              ' tilladt; håndterer z "by reference"
      Call Funktion(z)        ' tilladt; håndterer z "by reference"
    • ByVal
      Funktion(z)             ' tilladt; håndterer z "by value"
      Call Funktion((z))      ' tilladt; håndterer z "by value"
    • Ubrugelig
      'n = Funktion z         ' ubrugelig; parenteser kræves
      'Call Funktion z        ' ubrugelig; parenteser kræves

Siden er oprettet 25-12-2006 og sidst opdateret 20-02-2007 13:21.