Kontroll.sql
Forskjell mellom revisjon 1.46  1998/12/17 13:12:07  og  1999/10/05 17:23:31

Dette er en output fra programmet sdiff. Side-by-side-difference. Til venstre er
gammel versjon, til høyre ny. Midterst kan det finnes tegn |, < eller >.

|   betyr at linjen er endret.
>  betyr ny linje siden sist.
<  betyr at linjen er fjernet.

Noen steder kan |, < og > ligge litt skevt (pga bug i sdiff), men ikke så mye at det gjør noe.
Vi kan på forespørsel lage slike differansedokumenter mellom andre tidspunkt.

(huskelapp for sdiff
co -p1.46 kontroll.sql > /tmp/$$ ; sdiff -w216 -t /tmp/$$ kontroll.sql > ! resultatfil ; rm /tmp/$$
)

-- PL/SQL-kode, kjetilsk@usit.uio.no                                                                          -- PL/SQL-kode, kjetilsk@usit.uio.no
-- $Id: kontroll.sql,v 1.46 1998/12/17 13:12:07 so_opr Exp $                                               |  -- $Id: kontroll.sql,v 1.55 1999/10/05 17:23:31 so_opr Exp so_opr $
                                                                                                           |  --
                                                                                                           |  --
                                                                                                           |  --
                                                                                                           |  --               S O - K O N T R O L L M O D U L E N
                                                                                                           |  --
                                                                                                           >  --
--   OM PROGRAMMERINGSSPRÅKET PL/SQL OG PAKKEN/MODULEN NVB:                                                    --   OM PROGRAMMERINGSSPRÅKET PL/SQL OG PAKKEN/MODULEN NVB:
                                                                                                           |  --
--   Linjer som starter på -- er kommentarer.                                                                  --   Linjer som starter på -- er kommentarer.
--   En PL/SQL-pakke er en samling prosedyrer, funksjoner og pakkevariabler/pakkearrayer.                     --   En PL/SQL-pakke er en samling prosedyrer, funksjoner og pakkevariabler/pakkearrayer.
--   Denne filen definerer pakken nvb.                                                                        --   Denne filen definerer pakken nvb.
--   De viktigste prosedyrene/funksjonene her er:                                                             --   De viktigste prosedyrene/funksjonene her er:
--                                                                                                            --
--   * Kontroller(). Tar en vitnemålnøkkel og en kravkode som parametre.                                        --   * Kontroller(). Tar en vitnemålnøkkel og en kravkode som parametre.
--     Resultatet (SANN/USANN samt noen tall) legges i tabellen kontrollresultat.                             --     Resultatet (SANN/USANN samt noen tall) legges i tabellen kontrollresultat.
--     Kontroller() er den eneste prosedyren som er synlig utad i pakken nvb,                                 --     Kontroller() er den eneste prosedyren som er synlig utad i pakken nvb,
--     alle andre er hjelpeprosedyrer for denne.                                                              --     alle andre er hjelpeprosedyrer for denne.
--                                                                                                            --
--   * Kontroller_uttrykk() tar en vitnemålnøkkel og et kontrollradnr som parametre.                            --   * Kontroller_uttrykk() tar en vitnemålnøkkel og et kontrollradnr som parametre.
--     Dette er den egentlig prosedyren som utfører kontrollen rekursivt.                                      --     Dette er den egentlig prosedyren som utfører kontrollen rekursivt.
--                                                                                                            --
--   * Regn_ut_operand() tar en vitnemålnøkkel og en kontrollradoperand som                                     --   * Regn_ut_operand() tar en vitnemålnøkkel og en kontrollradoperand som
--     parametre.                                                                                             --     parametre.
--                                                                                                            --
--   Diverse oracle-funksjoner, hvordan de virker:                                                            --   Diverse oracle-funksjoner, hvordan de virker:
--                                                                                                            --
--   nvl(x, y)                                                                                                --   nvl(x, y)
--   Dersom x er null (dvs blank eller ingen verdi) returneres y, ellers x.                                   --   Dersom x er null (dvs blank eller ingen verdi) returneres y, ellers x.
--                                                                                                            --
--   decode(x, a1, a2, b1, b2, c1, c2, ..., y) virker slik:                                                   --   decode(x, a1, a2, b1, b2, c1, c2, ..., y) virker slik:
--   Function decode(x, a1, a2, b1, b2, c1, c2, ..., y)                                                       --   Function decode(x, a1, a2, b1, b2, c1, c2, ..., y)
--   begin                                                                                                    --   begin
--     case x of                                                                                              --     case x of
--       a1: return a2;                                                                                       --       a1: return a2;
--       b1: return b2;                                                                                       --       b1: return b2;
--       c1: return c2;                                                                                       --       c1: return c2;
--       .                                                                                                    --       .
--       .                                                                                                    --       .
--       .                                                                                                    --       .
--       else return y;                                                                                       --       else return y;
--     end;                                                                                                   --     end;
--   end;                                                                                                     --   end;
--                                                                                                            --
--   || er konkatenering, dvs sammenlegging, av strenger                                                      --   || er konkatenering, dvs sammenlegging, av strenger
--                                                                                                            --
--   rpad(s, x)                                                                                               --   rpad(s, x)
--   Returnerer strengen s med så mange spacer bak som skal til for at                                        --   Returnerer strengen s med så mange spacer bak som skal til for at
--   strengen får lengden x. F.eks rpad('Test',6) gir 'Test  '                                                 --   strengen får lengden x. F.eks rpad('Test',6) gir 'Test  '
--                                                                                                            --
--   ascii(c)                                                                                                 --   ascii(c)
--   Returnerer ascii-verdien til tegn c. ascii('A') gir 65, B gir 66 osv.                                    --   Returnerer ascii-verdien til tegn c. ascii('A') gir 65, B gir 66 osv.
--   Tilsvarer ord() i endel andre språk.                                                                      --   Tilsvarer ord() i endel andre språk.
--                                                                                                            --
                                                                                                           >  --   chr(tall)
                                                                                                           >  --   Returnerer tegnet som tilsvarer tallet i ascii. chr(65) gir A,
                                                                                                           >  --   chr(10) gir linjeskift. (Ihvertfall i unix)
                                                                                                           >  --
--   replace(s, ss1, ss2)                                                                                     --   replace(s, ss1, ss2)
--   Erstatter alle forekomster av substreng ss1 med ss2 i streng s og                                        --   Erstatter alle forekomster av substreng ss1 med ss2 i streng s og
--   returnerer dette. replace('AAXX10','XX','__') gir 'AA__10'                                               --   returnerer dette. replace('AAXX10','XX','__') gir 'AA__10'
--                                                                                                            --
--   like                                                                                                     --   like
--   Operator som sammenligner strenger mot "mønster". A like 'AA__10' gir true                               --   Operator som sammenligner strenger mot "mønster". A like 'AA__10' gir true
--   dersom A er en sekstegns streng, som starter på AA, ender på 10 og har to                                --   dersom A er en sekstegns streng, som starter på AA, ender på 10 og har to
--   vilkårlige tegn i midten. _ betyr altså et hvilket som helst tegn'. (% betyr                             --   vilkårlige tegn i midten. _ betyr altså et hvilket som helst tegn'. (% betyr
--   null, en eller flere hvilke som helst tegn, men % er ikke brukt i dette                                  --   null, en eller flere hvilke som helst tegn, men % er ikke brukt i dette
--   programmet).                                                                                             --   programmet).

-- KALLTRE SOM VISER ALLE PROSEDYRER/FUNKSJONER, OG HVORDAN DE KALLER HVERANDRE:                              -- KALLTRE SOM VISER ALLE PROSEDYRER/FUNKSJONER, OG HVORDAN DE KALLER HVERANDRE:
                                                                                                           |  --
-- Utenfra kalles:                                                                                            -- Utenfra kalles:
--                                                                                                            -- 
-- * Enten kontroller() med en vitnemålnr + kravkode ( + evt noe mer) som parametre                           -- * Enten kontroller() med en vitnemålnr + kravkode ( + evt noe mer) som parametre
--                                                                                                            -- 
-- * Eller kontroller10() som gjør det samme som kontroller(), men 10 ganger. Brukes                          -- * Eller kontroller10() som gjør det samme som kontroller(), men 10 ganger. Brukes
--   til testing/tidtakning.                                                                                  --   til testing/tidtakning.
--                                                                                                            -- 
-- * Eller kontroller_alle_vitnemaal().                                                                       -- * Eller kontroller_alle_vitnemaal().
--                                                                                                            --
-- Den siste tar selvfølgelig ikke inn vmnr som parameter.                                                    -- Den siste tar selvfølgelig ikke inn vmnr som parameter. 
--                                                                                                            --
-- I et kalltre representerer hver boks en subrutine (prosedyre eller funksjon eller                          -- I et kalltre representerer hver boks en subrutine (prosedyre eller funksjon eller
-- hva det heter, språkavhengig). Pilene sier at en rutine kaller en annen, null, en                          -- hva det heter, språkavhengig). Pilene sier at en rutine kaller en annen, null, en
-- eller flere ganger. Man ser rekursiviteten (eller "selvkallingen") ved at pilene                           -- eller flere ganger. Man ser rekursiviteten (eller "selvkallingen") ved at pilene
-- går i sirkel for kontroller_uttrykk og regn_ut_operand.                                                    -- går i sirkel for kontroller_uttrykk og regn_ut_operand.
--                                                                                                            -- 
--                              ~ ~ ~ ~ ~ ~ ~                                                                 --                              ~ ~ ~ ~ ~ ~ ~
--                             ~     vmnr    ~                                                                --                             ~     vmnr    ~
--                            ~    kravkode   ~                                                               --                            ~    kravkode   ~
--                             ~             ~                                                                --                             ~             ~ 
--                              ~ ~ ~ ~ ~ ~ ~                                                                 --                              ~ ~ ~ ~ ~ ~ ~ 
--                               .    .    .                                                                  --                               .    .    .
--                               .    .    .                                                                  --                               .    .    .
--                               .    .    .                                                                  --                               .    .    .
--                               V    .    V                                                                  --                               V    .    V
--         ________________________   .   _____________________________________                               --         ________________________   .   _____________________________________ 
--        | procedure kontroller10 |  .  | procedure kontroller_alle_vitnemaal |                              --        | procedure kontroller10 |  .  | procedure kontroller_alle_vitnemaal |
--        `------------------------'  .  `-------------------------------------'                              --        `------------------------'  .  `-------------------------------------'
--                 |                  .                   |                                                   --                 |                  .                   |
--                 |                  V                   |                                                   --                 |                  V                   |
--                 |      ______________________          |                                                   --                 |      ______________________          |
--                 `---> | procedure kontroller | <-------'                                                   --                 `---> | procedure kontroller | <-------'
--                       `----------------------'                                                             --                       `----------------------'
--                                    |                                                                       --                                    |
--                                    |                                                                       --                                    |
--                                    |                                                                       --                                    |
--                                    V                                                                       --                                    V
--                     _____________________________         _____________________________                    --                     _____________________________         _____________________________ 
--            ,-----> | function kontroller_uttrykk | ----> | procedure ikke_oppbrukt     |                   --            ,-----> | function kontroller_uttrykk | ----> | procedure ikke_oppbrukt     |
--            |       `-----------------------------'       `-----------------------------'                   --            |       `-----------------------------'       `-----------------------------'
--            |             |         |   |   |              _____________________________                    --            |             |         |   |   |              _____________________________ 
--            |             |         |   |   `-----------> | procedure logg_sluttrapport |                   --            |             |         |   |   `-----------> | procedure logg_sluttrapport |
--            |             |         |   |                 `-----------------------------'                   --            |             |         |   |                 `-----------------------------'
--            |             |         |   |                  _____________________________                    --            |             |         |   |                  _____________________________ 
--            |             |         |   `---------------> | procedure logg_melding      |                   --            |             |         |   `---------------> | procedure logg_melding      |
--            |             |         |                     `-----------------------------'                   --            |             |         |                     `-----------------------------'
--            |             |         |                                                                       --            |             |         |
--            |             V         |                                                                       --            |             V         |
--    ____________________________    |          __________________________                                   --    ____________________________    |          __________________________ 
--   |  function regn_ut_operand  |   `-------> |  function regn_ut_samme  |                                  --   |  function regn_ut_operand  |   `-------> |  function regn_ut_samme  |
--   `----------------------------'             `--------------------------'                                  --   `----------------------------'             `--------------------------'
--               |          |                                                                                 --               |          |
--               |          `-----------------                                                                --               |          `----------------- 
--               |                            |                                                               --               |                            |
--               V                            V                                                               --               V                            V
--   ___________________________    _________________________                                                 --   ___________________________    _________________________ 
--  | function get_vitnemaalfag |  | procedure sett_oppbrukt |                                                --  | function get_vitnemaalfag |  | procedure sett_oppbrukt |
--  `---------------------------'  `-------------------------'                                                --  `---------------------------'  `-------------------------'
--                                                                                                            --
--                                                                                                            --
--                                                                                                            --
-- Smårutiner som kan kalles fra hvor som helst:                                                           |  --  Smårutiner som kan kalles fra hvor som helst:
--                                                                                                            -- 
--     ___________________________                                                                            --     ___________________________ 
--    |     function divider      |                                                                           --    |     function divider      |
--    `---------------------------'                                                                           --    `---------------------------'
--                                                                                                            --    
--     ___________________________                                                                            --     ___________________________ 
--    |     procedure logg        |                                                                           --    |     procedure logg        |
--    `---------------------------'                                                                           --    `---------------------------'
--                                                                                                            --    
--     ___________________________                                                                            --     ___________________________ 
--    |     procedure error       |                                                                           --    |     procedure error       |
--    `---------------------------'                                                                           --    `---------------------------'
--                                                                                                            --
--     ___________________________                                                                            --     ___________________________ 
--    |  function karakter_tekst  |                                                                           --    |  function karakter_tekst  |
--    `---------------------------'                                                                           --    `---------------------------'
--                                                                                                            --

-- HJELPETABELLER ------------------------------------------------------------------                          -- HJELPETABELLER ------------------------------------------------------------------

drop table oppbrukte_fag;                                                                                  |  set echo off
create table oppbrukte_fag (                                                                               |  drop table v_oppbrukte_fag;
                                                                                                           >  create table v_oppbrukte_fag (
  fagkode varchar2(6) not null primary key,                                                                     fagkode varchar2(6) not null primary key,
  nr      number(4)   not null                                                                                  nr      number(4)   not null
);                                                                                                            );
create index i_oppbrukte_fag on oppbrukte_fag(nr);                                                         |  create index i_oppbrukte_fag on v_oppbrukte_fag(nr);

drop table nvb_logg;                                                                                       |  -- drop table v_nvb_logg;
create table nvb_logg (                                                                                    |  create table v_nvb_logg (
                                                                                                           >    vmnr varchar2(17),
                                                                                                           >    linjenr number(6),
  txt varchar2(2000)                                                                                            txt varchar2(2000)
);                                                                                                            );
                                                                                                           |  create index i_nvb_logg on v_nvb_logg (vmnr);
                                                                                                           <

-- PAKKEHODE (INTERFACE PUBLIC evt .h-filen) ------------------------------------------                       -- PAKKEHODE (INTERFACE PUBLIC evt .h-filen) ------------------------------------------
create or replace package  nvb  as                                                                            create or replace package  nvb  as

  -- Procedure kontroller tar fra 4 til 6 parametre, de to siste er valgfrie:                                   -- Procedure kontroller tar fra 4 til 6 parametre, de to siste er valgfrie:
  --                                                                                                            --
  -- * Den første er vitnemålsnr                                                                                -- * Den første er vitnemålsnr
  -- * Den andre er kravkoden man skal kontrollere mot. Hvis f.eks. #A:=B og C;                                 -- * Den andre er kravkoden man skal kontrollere mot. Hvis f.eks. #A:=B og C;
  --   er parset inn i basen, så er A, B og C lovlige kravkoder. Vanlige kravkoder                              --   er parset inn i basen, så er A, B og C lovlige kravkoder. Vanlige kravkoder
  --   er f.eks. KONTROLL_AF, KONTROLL_ØA eller GSK.                                                            --   er f.eks. KONTROLL_AF, KONTROLL_ØA eller GSK.
  --                                                                                                            --
  -- * Tredje parameter er loggenivå. Default nivå er 4 dersom ikke angitt.                                     -- * Tredje parameter er loggenivå. Default nivå er 4 dersom ikke angitt.
  --   Jo høyere loggenivåtall, jo mer logges.                                                                  --   Jo høyere loggenivåtall, jo mer logges.
  --   0   Ikke logg noe                                                                                        --   0   Ikke logg noe
  --   1   Logg bare systemfeil (ERROR)                                                                         --   1   Logg bare systemfeil (ERROR)
  --   2   Logg USANN-meldinger. F.eks. #A [usann "...tekst..."] := B og C;                                     --   2   Logg USANN-meldinger. F.eks. #A [usann "...tekst..."] := B og C;
  --       Og overskrifter. F.eks. #A := B [over "Dette er en overskrift"] og C;                           |    --       Og vitnemålskille.
  --   3   Logg SANN-meldinger. F.eks. #A[sann "...tekst..."] := B og C;                                        --   3   Logg SANN-meldinger. F.eks. #A[sann "...tekst..."] := B og C;
                                                                                                           >    --       Og overskrifter. F.eks. #A := B [over "Dette er en overskrift"] og C;
  --   4   Logg hvilke fag som er "oppbrukt", FAGLOGG.                                                          --   4   Logg hvilke fag som er "oppbrukt", FAGLOGG.
  --   5   Sluttrapport                                                                                         --   5   Sluttrapport
  --   6   HELE-sluttrapport (ser ut som en sluttrapport)                                                       --   6   HELE-sluttrapport (ser ut som en sluttrapport)
  --   7   Logg kravuttrykkraden idet man starter kontroll av den                                               --   7   Logg kravuttrykkraden idet man starter kontroll av den
  --   8   Logg operander med resultat som gir SANN, og kjøring av ikke_oppbrukt()                              --   8   Logg operander med resultat som gir SANN, og kjøring av ikke_oppbrukt()
  --   9   Logg operander med resultat uansett SANN, USANN eller tall.                                          --   9   Logg operander med resultat uansett SANN, USANN eller tall.
  --  10   og høyere: udefinert                                                                            |    --  10   Viser hvilke uttrykk som skippes (trenger ikke regnes ut pga optimalisering)
                                                                                                           >    --  11   og høyere: udefinert

  --                                                                                                            --
  -- * Den fjerde er valgfri. Hvis den er gitt inneholder den kravversjon. Dvs                                  -- * Den fjerde er valgfri. Hvis den er gitt inneholder den kravversjon. Dvs
  --   hvilken parsefil kravkoden stammer fra. Parseren setter kravversjon til                                  --   hvilken parsefil kravkoden stammer fra. Parseren setter kravversjon til
  --   filnavn, med store bokstaver, på den filen kravene ble lest fra. Unntatt                                 --   filnavn, med store bokstaver, på den filen kravene ble lest fra. Unntatt
  --   eventuelle endelser. F.eks. fil testkrav5.txt blir kravversjon TESTKRAV5.                                --   eventuelle endelser. F.eks. fil testkrav5.txt blir kravversjon TESTKRAV5.
  --   Etterhvert må vi bli enige med SUE hvordan versjonene skal kodes, f.eks.                                 --   Etterhvert må vi bli enige med SUE hvordan versjonene skal kodes, f.eks.
  --   dato og A, B, C hvis det er flere versjoner på samme dag. Dersom fjerde                                  --   dato og A, B, C hvis det er flere versjoner på samme dag. Dersom fjerde
  --   parameter ikke er angitt velger procedure kontroller den nyeste                                          --   parameter ikke er angitt velger procedure kontroller den nyeste
  --   kravversjon som gitt kravkode finnes i. Dvs. den som ble sist parset.                                    --   kravversjon som gitt kravkode finnes i. Dvs. den som ble sist parset.
  --   Dersom kravkode TU8 finnes i både kravversjon TESTKRAV5 og TESTKRAV6,                                    --   Dersom kravkode TU8 finnes i både kravversjon TESTKRAV5 og TESTKRAV6,
  --   velges TESTKRAV6 dersom den ble parset inn i basen på et senere tidspunkt                                --   velges TESTKRAV6 dersom den ble parset inn i basen på et senere tidspunkt
  --   enn TESTKRAV5.                                                                                           --   enn TESTKRAV5.

  procedure kontroller (                                                                                        procedure kontroller (
    p_vmnr             in  kontrollresultat.vmnr%type,                                                     |      p_vmnr             in  v_kontrollresultat.vmnr%type,
    p_kravkode         in  kontrollresultat.kravkode%type,                                                 |      p_kravkode         in  v_kontrollresultat.kravkode%type,
    p_loggnivaa        in  number default 4,                                                                      p_loggnivaa        in  number default 4,
    p_kravversjonkode  in  kontrollresultat.kravversjonkode%type default null                              |      p_kravversjonkode  in  v_kontrollresultat.kravversjonkode%type default null
  );                                                                                                            );

  procedure kontroller10 (                                                                                      procedure kontroller10 (
    p_vmnr             in  kontrollresultat.vmnr%type,                                                     |      p_vmnr             in  v_kontrollresultat.vmnr%type,
    p_kravkode         in  kontrollresultat.kravkode%type,                                                 |      p_kravkode         in  v_kontrollresultat.kravkode%type,
    p_loggnivaa        in  number default 4,                                                                      p_loggnivaa        in  number default 4,
    p_kravversjonkode  in  kontrollresultat.kravversjonkode%type default null                              |      p_kravversjonkode  in  v_kontrollresultat.kravversjonkode%type default null
  );                                                                                                            );

  procedure kontroller_alle_vitnemaal(                                                                          procedure kontroller_alle_vitnemaal(
    p_kravkode         in  kontrollresultat.kravkode%type,                                                 |      p_kravkode         in  v_kontrollresultat.kravkode%type,
    p_loggnivaa        in  number default 4,                                                                      p_loggnivaa        in  number default 4,
    p_kravversjonkode  in  kontrollresultat.kravversjonkode%type default null                              |      p_kravversjonkode  in  v_kontrollresultat.kravversjonkode%type default null
  );                                                                                                            );

end nvb;                                                                                                      end nvb;
/                                                                                                             /

-- PAKKEKROPP (IMPLEMENTATION PRIVATE evt .c-filen) -------------------------------------------------         -- PAKKEKROPP (IMPLEMENTATION PRIVATE evt .c-filen) -------------------------------------------------
create or replace package body  nvb  as                                                                       create or replace package body  nvb  as

  -- DEFINERER TYPER                                                                                            -- DEFINERER TYPER

  -- Returneres av kontroller_uttrykk og regn_ut_operand                                                        -- Returneres av kontroller_uttrykk og regn_ut_operand
  type resultattype is record (                                                                                 type resultattype is record (

    -- Som i kontrollresultat-tabellen:                                                                           -- Som i kontrollresultat-tabellen:
    resultattypekode     kontrollresultat.resultattypekode%type,                                           |      resultattypekode     v_kontrollresultat.resultattypekode%type,
    resultatkode         kontrollresultat.resultatkode%type,                                               |      resultatkode         v_kontrollresultat.resultatkode%type,
    resultattall         kontrollresultat.resultattall%type,                                               |      resultattall         v_kontrollresultat.resultattall%type,
    antall_fag           kontrollresultat.antall_fag%type,                                                 |      antall_fag           v_kontrollresultat.antall_fag%type,
    omfang               kontrollresultat.omfang%type,                                                     |      omfang               v_kontrollresultat.omfang%type,
    vekt                 kontrollresultat.vekt%type,                                                       |      vekt                 v_kontrollresultat.vekt%type,
    antall_tallkar       kontrollresultat.antall_tallkar%type,                                             |      antall_tallkar       v_kontrollresultat.antall_tallkar%type,
    sum_tallkar          kontrollresultat.sum_tallkar%type,                                                |      sum_tallkar          v_kontrollresultat.sum_tallkar%type,
    snitt_tallkar        kontrollresultat.snitt_tallkar%type,                                              |      snitt_tallkar        v_kontrollresultat.snitt_tallkar%type,
    fordypninger_foert   kontrollresultat.snitt_tallkar%type,                                              |      fordypninger_foert   v_kontrollresultat.snitt_tallkar%type,

    -- Fra sist oppbrukte fag på vitnemålet:                                                                        -- Fra sist oppbrukte fag på vitnemålet:
    fagkode              fag.fagkode%type,                                                                 |      fagkode              v_fag.fagkode%type,
    karakter_eksamen     number(2),                                                                               karakter_eksamen     number(2),
    karakter_standpunkt  number(2),                                                                               karakter_standpunkt  number(2),
    obligatorisk_eksamen boolean,                                                                                 obligatorisk_eksamen boolean,
    privatistkode        vitnemaalfag.privatistkode%type                                                   |      privatistkode        v_vitnemaalfag.privatistkode%type

  );                                                                                                            );

  -- Globale variable innenfor pakke nvb                                                                        -- Globale variable innenfor pakke nvb
  oppbrukte_fag_siste_nr  number;                                                                               oppbrukte_fag_siste_nr  number;
  kravuttrykknr_current   number;                                                                               kravuttrykknr_current   number;
  denne                   resultattype;                                                                         denne                   resultattype;
  resultat_SANN           resultattype;                                                                         resultat_SANN           resultattype;
  resultat_USANN          resultattype;                                                                         resultat_USANN          resultattype;
  loggnivaa_current       number;                                                                               loggnivaa_current       number;

  -- Einars current vmnr                                                                                   |    -- Brukes i procedure logg
  c_vmnr                  number;                                                                          |    c_vmnr                  varchar2(17);
                                                                                                           >    linjenr_logg            number;

  type boolean_tabell is table of boolean index by binary_integer;                                              type boolean_tabell is table of boolean index by binary_integer;
  type integer_tabell is table of integer index by binary_integer;                                              type integer_tabell is table of integer index by binary_integer;
  type string_tabell  is table of string(80) index by binary_integer;                                           type string_tabell  is table of string(80) index by binary_integer;
  har_melding             boolean_tabell;                                                                       har_melding             boolean_tabell;
  loggnivaa               integer_tabell;                                                                       loggnivaa               integer_tabell;
  kravkode                string_tabell;                                                                        kravkode                string_tabell;
  skip_kravuttrykk        boolean_tabell;                                                                       skip_kravuttrykk        boolean_tabell;
  tom_boolean_tabell      boolean_tabell;                                                                       tom_boolean_tabell      boolean_tabell;
  tom_integer_tabell      integer_tabell;                                                                       tom_integer_tabell      integer_tabell;
  tom_string_tabell       string_tabell;                                                                        tom_string_tabell       string_tabell;

  -- Brukes til å logge diverse                                                                                  -- Brukes til å logge diverse
  procedure logg (                                                                                              procedure logg (
    p_txt       varchar2,                                                                                         p_txt       varchar2,
    p_loggnivaa number    default 9                                                                               p_loggnivaa number    default 9
  ) is                                                                                                          ) is
    kunr varchar2(10);                                                                                            kunr varchar2(10);
  begin                                                                                                         begin
    if p_loggnivaa <= loggnivaa_current then                                                                      if p_loggnivaa <= loggnivaa_current then
      if loggnivaa_current >= 7 then                                                                                if loggnivaa_current >= 7 then
        kunr := rpad(nvl(kravuttrykknr_current,-1),6);                                                                kunr := rpad(nvl(kravuttrykknr_current,-1),6);
      end if;                                                                                                       end if;
      insert into nvb_logg values ( kunr || p_txt );                                                       |        linjenr_logg := nvl(linjenr_logg,0) + 1;
                                                                                                           >        insert into v_nvb_logg values ( c_vmnr, linjenr_logg, kunr || replace(p_txt,'£',chr(10)) );
                                                                                                           >        -- chr(10) er linjeskift, £ er "spesialtegn" i kravspråket/parseren som betyr linjeskift
    end if;                                                                                                       end if;
  end;                                                                                                          end;

  -- Som logg(), men setter ERROR foran                                                                         -- Som logg(), men setter ERROR foran
  procedure error (p_txt varchar2) is                                                                           procedure error (p_txt varchar2) is
  begin                                                                                                         begin
    logg('ERROR:  '||p_txt, -1);                                                                                  logg('ERROR:  '||p_txt, -1);
  end;                                                                                                          end;

                                                                                                           >  -- Function karakter_tekst brukes foreløpig kun i logg_melding,
                                                                                                           >  -- for å skrive ut karakter 'D' istedenfor -68 (f.eks.)
                                                                                                           >
                                                                                                           >    function karakter_tekst (karakter_tall number)
                                                                                                           >    return varchar2 is
                                                                                                           >    begin
                                                                                                           >      if karakter_tall < 0 then
                                                                                                           >        return ''''||chr(-karakter_tall)||'''';
                                                                                                           >      else
                                                                                                           >        return chr(karakter_tall+ascii('0'));
                                                                                                           >      end if;
                                                                                                           >    end;
                                                                                                           >
                                                                                                           >

-- Et vanlig krav i kravspråket kan se f.eks. slik ut:                                                        -- Et vanlig krav i kravspråket kan se f.eks. slik ut:
-- # A := B og C;                                                                                             -- # A := B og C;
--                                                                                                            -- 
-- Man kan legge på meldinger av forskjellige typer, f.eks. slik                                           |  -- Et uttrykk kan ha en tilhørende meldingsdefinisjon, f.eks. slik:
--                                                                                                            -- 
-- # A [...MELDINGSDEFINISJON...] := B og C [...MELDINGSDEFINISJON...];                                       -- # A [...MELDINGSDEFINISJON...] := B og C [...MELDINGSDEFINISJON...];
--                                                                                                            -- 
-- En meldingsdefinisjon er en liste av en eller flere meldinger av typene sann,                           |  -- En meldingsdefinisjon er en liste av en eller flere meldinger. Hver melding er av
-- usann, faglogg, logg eller overskrift. Et krav i kravspåket kan se slik ut:                             |  -- type SANN, USANN, FAGLOGG, LOGG eller OVERSKRIFT. Et krav kan da f.eks. se slik ut:
--                                                                                                            -- 
-- # A [sann  "Krav A er ok"                                                                                  -- # A [sann  "Krav A er ok"
--      usann "Krav A ikke ok"                                                                                --      usann "Krav A ikke ok"
--      logg  5                                                                                               --      logg  5
--      faglogg "gir fodypning"                                                                               --      faglogg "gir fodypning"
--      overskrift "Starter kontroll av krav A"] := B og C;                                                   --      overskrift "Starter kontroll av krav A"] := B og C;
--                                                                                                            -- 

-- Function karakter_tekst brukes foreløpig kun i logg_melding,                                            <
-- for å skrive ut karakter 'D' istedenfor -68 (f.eks.)                                                    <
                                                                                                           <
  function karakter_tekst (karakter_tall number)                                                           <
  return varchar2 is                                                                                       <
  begin                                                                                                    <
    if karakter_tall < 0 then                                                                              <
      return ''''||chr(-karakter_tall)||'''';                                                              <
    else                                                                                                   <
      return chr(karakter_tall+ascii('0'));                                                                <
    end if;                                                                                                <
  end;                                                                                                     <
                                                                                                           <
                                                                                                           <
                                                                                                           <
-- Parseren her vil opprette fem rader i tabellen kravmelding for krav A, en for                              -- Parseren her vil opprette fem rader i tabellen kravmelding for krav A, en for
-- hver kravtype. Prosedyren logg_melding kalles fra kontroller_uttrykk, og den                               -- hver kravtype. Prosedyren logg_melding kalles fra kontroller_uttrykk, og den
-- finner ut om gitt kravuttrykk har meldinger koblet til seg. Logg_melding kunne                             -- finner ut om gitt kravuttrykk har meldinger koblet til seg. Logg_melding kunne
-- ha byttet navn til kanskje_logg_melding                                                                    -- ha byttet navn til kanskje_logg_melding

                                                                                                           >
  procedure logg_melding (                                                                                      procedure logg_melding (
    p_kravversjonkode        kravuttrykk.kravversjonkode%type,                                             |      p_kravversjonkode        v_kravuttrykk.kravversjonkode%type,
    p_kravuttrykknr          kravuttrykk.kravuttrykknr%type,                                               |      p_kravuttrykknr          v_kravuttrykk.kravuttrykknr%type,         
    p_resultat               resultattype,                                                                        p_resultat               resultattype,
    p_oppbrukte_fag_fom      number default 9999,                                                                 p_oppbrukte_fag_fom      number default 9999,
    p_kravuttrykknr_forrige  kravuttrykk.kravuttrykknr%type default -1                                     |      p_kravuttrykknr_forrige  v_kravuttrykk.kravuttrykknr%type default -1
  )                                                                                                             )
  is                                                                                                            is
    ln          number;                                                                                           ln          number;
    tekst       kravmelding.meldingtekst%type;                                                             |      tekst       v_kravmelding.meldingtekst%type;
  begin                                                                                                         begin

    -- Siden logg_melding kalles en eller to ganger i hver kontroller_uttrykk                                     -- Siden logg_melding kalles en eller to ganger i hver kontroller_uttrykk
    -- er det viktig at den går raskt. For de aller fleste kravuttrykkene finnes                                   -- er det viktig at den går raskt. For de aller fleste kravuttrykkene finnes
    -- det ingen meldinger, går isåfall ut av logg_melding med en gang før man                                       -- det ingen meldinger, går isåfall ut av logg_melding med en gang før man
    -- setter igang en dyr select.                                                                                -- setter igang en dyr select.
    if loggnivaa_current < 2                                                                                      if loggnivaa_current < 2
    or not har_melding.exists(p_kravuttrykknr)                                                                    or not har_melding.exists(p_kravuttrykknr)
    or p_kravuttrykknr = nvl(p_kravuttrykknr_forrige,-1) then                                                     or p_kravuttrykknr = nvl(p_kravuttrykknr_forrige,-1) then
      return;                                                                                                       return;
    end if;                                                                                                       end if;
                                                                                                               
    for melding in (                                                                                              for melding in (
      select kravversjonkode,kravuttrykknr,meldingtekst,kravmeldingtypekode                                         select kravversjonkode,kravuttrykknr,meldingtekst,kravmeldingtypekode
      from kravmelding                                                                                     |        from v_kravmelding
      where kravversjonkode=p_kravversjonkode                                                                       where kravversjonkode=p_kravversjonkode
      and kravuttrykknr=p_kravuttrykknr                                                                             and kravuttrykknr=p_kravuttrykknr
      and (                                                                                                         and (
           kravmeldingtypekode = p_resultat.resultatkode and p_resultat.resultattypekode = 'B'                           kravmeldingtypekode = p_resultat.resultatkode and p_resultat.resultattypekode = 'B'
        or kravmeldingtypekode = 'FAGLOGG' and p_resultat.resultattypekode = 'B' and p_resultat.resultatko            or kravmeldingtypekode = 'FAGLOGG' and p_resultat.resultattypekode = 'B' and p_resultat.resultatko
        or kravmeldingtypekode = 'OVER' and p_oppbrukte_fag_fom = 9999                                                or kravmeldingtypekode = 'OVER' and p_oppbrukte_fag_fom = 9999
      )                                                                                                             )
      order by decode(kravmeldingtypekode,                                                                          order by decode(kravmeldingtypekode,
                      'LOGG',   1,                                                                                                  'LOGG',   1,
                      'OVER',   2,                                                                                                  'OVER',   2,
                      'SANN',   3,                                                                                                  'SANN',   3,
                      'USANN',  4,                                                                                                  'USANN',  4,
                      'FAGLOGG',5, 9)                                                                                               'FAGLOGG',5, 9)
    )                                                                                                             )
    loop                                                                                                          loop
      tekst := melding.meldingtekst;                                                                                tekst := melding.meldingtekst;
      if instr(tekst,'$') > 0 then                                                                                  if instr(tekst,'$') > 0 then
        tekst := replace(tekst,'$TALL',  denne.resultattall);                                                         tekst := replace(tekst,'$TALL',  denne.resultattall);
        tekst := replace(tekst,'$OMFANG',denne.omfang);                                                               tekst := replace(tekst,'$OMFANG',denne.omfang);
        tekst := replace(tekst,'$VEKT',  denne.vekt);                                                                 tekst := replace(tekst,'$VEKT',  denne.vekt);
        tekst := replace(tekst,'$ANTTK', denne.antall_tallkar);                                                       tekst := replace(tekst,'$ANTTK', denne.antall_tallkar);
        tekst := replace(tekst,'$SUMTK', denne.sum_tallkar);                                                          tekst := replace(tekst,'$SUMTK', denne.sum_tallkar);
        tekst := replace(tekst,'$SNTTK', to_char(denne.snitt_tallkar,'9.99'));                                        tekst := replace(tekst,'$SNTTK', to_char(denne.snitt_tallkar,'9.99'));
        tekst := replace(tekst,'$SKAR',  karakter_tekst(denne.karakter_standpunkt));                                  tekst := replace(tekst,'$SKAR',  karakter_tekst(denne.karakter_standpunkt));
        tekst := replace(tekst,'$EKAR',  karakter_tekst(denne.karakter_eksamen));                                     tekst := replace(tekst,'$EKAR',  karakter_tekst(denne.karakter_eksamen));
        tekst := replace(tekst,'$ANTFF', denne.fordypninger_foert);                                                   tekst := replace(tekst,'$ANTFF', denne.fordypninger_foert);
        tekst := replace(tekst,'$FAGKODE', denne.fagkode);                                                            tekst := replace(tekst,'$FAGKODE', denne.fagkode);
        if instr(tekst,'$')>0 then                                                                                    if instr(tekst,'$')>0 then
          error('Ukjent $-variabel i "'||tekst||'"');                                                                   error('Ukjent $-variabel i "'||tekst||'"');
        end if;                                                                                                       end if;
      end if;                                                                                                       end if;
      if melding.kravmeldingtypekode = 'FAGLOGG' then                                                               if melding.kravmeldingtypekode = 'FAGLOGG' then
        tekst := substr(tekst,1,30)||':';                                                                             tekst := substr(tekst,1,30)||':';
        for ofag in (                                                                                                 for ofag in (
          select ofag.nr, ofag.fagkode, substr(f.fagnavn_bokmaal,1,30) fagnavn, f.omfang                                select ofag.nr, ofag.fagkode, substr(f.fagnavn_bokmaal,1,30) fagnavn, f.omfang
          from oppbrukte_fag ofag, fag f                                                                   |            from v_oppbrukte_fag ofag, v_fag f
          where ofag.fagkode = f.fagkode and ofag.nr >= p_oppbrukte_fag_fom                                             where ofag.fagkode = f.fagkode and ofag.nr >= p_oppbrukte_fag_fom
          order by ofag.nr                                                                                              order by ofag.nr
        )                                                                                                             )
        loop                                                                                                          loop
          logg( rpad(tekst,31) || rpad(ofag.fagkode,7) || rpad(ofag.fagnavn,51),4 );                                    logg( rpad(tekst,31) || rpad(ofag.fagkode,7) || rpad(ofag.fagnavn,51),4 );
          tekst := ' ';                                                                                                 tekst := ' ';
        end loop;                                                                                                     end loop;

      elsif melding.kravmeldingtypekode = 'OVER' then                                                               elsif melding.kravmeldingtypekode = 'OVER' then
        logg('',2);                                                                                        |          logg('',3);
        logg(tekst,2);                                                                                     |          logg(tekst,3);
      elsif melding.kravmeldingtypekode in ('SANN','USANN') then                                                    elsif melding.kravmeldingtypekode in ('SANN','USANN') then
        if    melding.kravmeldingtypekode = 'SANN' then ln := 3; else ln := 2; end if;                                if    melding.kravmeldingtypekode = 'SANN' then ln := 3; else ln := 2; end if;
        logg(                                                                                                         logg(
--             'MELDING FOR '           ||                                                                    --             'MELDING FOR '           ||
--             melding.kravversjonkode  ||' '||                                                               --             melding.kravversjonkode  ||' '||
--             melding.kravuttrykknr    ||' '||                                                               --             melding.kravuttrykknr    ||' '||
--             p_resultat.resultatkode  ||':  '||                                                             --             p_resultat.resultatkode  ||':  '||
               c_vmnr                   ||': '||                                                           |  --             c_vmnr                   ||': '||
             tekst                                                                                                         tekst
        ,ln                                                                                                           ,ln
        );                                                                                                            );
      end if;                                                                                                       end if;
    end loop;                                                                                                     end loop;
  end;                                                                                                          end;

  procedure logg_sluttrapport (                                                                                 procedure logg_sluttrapport (
    p_vmnr            vitnemaal.vmnr%type,                                                                 |      p_vmnr            v_vitnemaal.vmnr%type,
    p_resultat        resultattype,                                                                               p_resultat        resultattype,
    p_kravversjonkode krav.kravversjonkode%type,                                                           |      p_kravversjonkode v_krav.kravversjonkode%type,
    p_kravkode        krav.kravkode%type,                                                                  |      p_kravkode        v_krav.kravkode%type,
    p_loggnivaa       number default 6                                                                            p_loggnivaa       number default 6
  )                                                                                                             )
  is                                                                                                            is
    skrevet_foer   boolean := false;                                                                              skrevet_foer   boolean := false;
    vm             vitnemaal%rowtype;                                                                      |      vm             v_vitnemaal%rowtype;
  begin                                                                                                         begin 
    logg('',p_loggnivaa);                                                                                         logg('',p_loggnivaa);
    logg('',p_loggnivaa);                                                                                         logg('',p_loggnivaa);
    logg('OMF FAGKODE FAGNAVN (bokmålsversjonen)     SKAR EKAR FF',p_loggnivaa);                                   logg('OMF FAGKODE FAGNAVN (bokmålsversjonen)     SKAR EKAR FF',p_loggnivaa);
    logg('--- ------- ------------------------------ ---- ---- --',p_loggnivaa);                                  logg('--- ------- ------------------------------ ---- ---- --',p_loggnivaa);

    -- Logger vitnemålet, først de som er oppbrukte                                                                 -- Logger vitnemålet, først de som er oppbrukte
    for ofag in (                                                                                                 for ofag in (
      select                                                                                                        select
        ofag.fagkode ofagkode,                                                                                        ofag.fagkode ofagkode,
        f.fagkode,                                                                                                    f.fagkode,
        f.fagnavn_bokmaal,                                                                                            f.fagnavn_bokmaal,
        f.omfang,                                                                                                     f.omfang,
        nvl(vf.karakter_standpunkt,'-') karakter_standpunkt,                                                          nvl(vf.karakter_standpunkt,'-') karakter_standpunkt,
        nvl(vf.karakter_eksamen,'-') karakter_eksamen,                                                                nvl(vf.karakter_eksamen,'-') karakter_eksamen,
        decode(vf.fordypningsfag,'J','F',null) ff                                                                     decode(vf.fordypningsfag,'J','F',null) ff
      from                                                                                                          from
        fag f,                                                                                                        fag f,
        vitnemaalfag vf,                                                                                              vitnemaalfag vf,
        oppbrukte_fag ofag                                                                                 |          v_oppbrukte_fag ofag
      where                                                                                                         where
        f.fagkode = ofag.fagkode(+) and                                                                               f.fagkode = ofag.fagkode(+) and
        f.fagkode = vf.fagkode and                                                                                    f.fagkode = vf.fagkode and
        vf.vmnr = p_vmnr                                                                                              vf.vmnr = p_vmnr
      order by                                                                                                      order by
        decode(ofag.fagkode,null,p_loggnivaa,0), vf.linjenr, f.fagkode                                                decode(ofag.fagkode,null,p_loggnivaa,0), vf.linjenr, f.fagkode
    )                                                                                                             )
    loop                                                                                                          loop
      if ofag.ofagkode is null and not skrevet_foer then                                                            if ofag.ofagkode is null and not skrevet_foer then
        logg('',p_loggnivaa);                                                                                         logg('',p_loggnivaa);
        logg('Fag som ikke ble brukt i kontrollen:',p_loggnivaa);                                                     logg('Fag som ikke ble brukt i kontrollen:',p_loggnivaa);
        skrevet_foer := true;                                                                                         skrevet_foer := true;
      end if;                                                                                                       end if;
      logg(lpad(ofag.omfang,3)         ||' '||                                                             |        logg(lpad(ofag.omfang||' ',4)         ||
           rpad(ofag.fagkode,8)             ||                                                                           rpad(ofag.fagkode,8)             ||
           rpad(ofag.fagnavn_bokmaal,30)    ||                                                                           rpad(ofag.fagnavn_bokmaal,30)    ||
           lpad(ofag.karakter_standpunkt,5) ||                                                                           lpad(ofag.karakter_standpunkt,5) ||
           lpad(ofag.karakter_eksamen,5)    ||                                                                           lpad(ofag.karakter_eksamen,5)    ||
           lpad(ofag.ff,3)                                                                                               lpad(ofag.ff,3)
      ,p_loggnivaa                                                                                                  ,p_loggnivaa
      );                                                                                                            );
    end loop;                                                                                                     end loop;

    select * into vm from vitnemaal                                                                        |      select * into vm from v_vitnemaal
    where vmnr = p_vmnr;                                                                                          where vmnr = p_vmnr;

    -- Logger resultatet                                                                                          -- Logger resultatet
    logg('',p_loggnivaa);                                                                                         logg('',p_loggnivaa);
    logg('Vitnemål:                      '|| vm.vmnr||'   '||                                                      logg('Vitnemål:                      '|| vm.vmnr||'   '||
                                             vm.foedtdato||' '||                                                                                           vm.foedtdato||' '||
                                             vm.personnummer||' '||                                                                                        vm.personnummer||' '||
                                             vm.regnr||' '||                                                                                               vm.regnr||' '||
                                             vm.elevnavn, p_loggnivaa);                                                                                    vm.elevnavn, p_loggnivaa);

    logg('Krav (kravversjon):            '||p_kravkode||' ('||p_kravversjonkode||')', p_loggnivaa);               logg('Krav (kravversjon):            '||p_kravkode||' ('||p_kravversjonkode||')', p_loggnivaa);
    logg('Antall fag krav:               '||p_resultat.antall_fag, p_loggnivaa);                                  logg('Antall fag krav:               '||p_resultat.antall_fag, p_loggnivaa);
    logg('Vekt:                          '||p_resultat.vekt, p_loggnivaa);                                        logg('Vekt:                          '||p_resultat.vekt, p_loggnivaa);

    logg('Beregnet:      Tallkarakterer: '||p_resultat.antall_tallkar||' stk., '||                                logg('Beregnet:      Tallkarakterer: '||p_resultat.antall_tallkar||' stk., '||
                                    'sum '||p_resultat.sum_tallkar||                                                                              'sum '||p_resultat.sum_tallkar||
                                ', snitt '||to_char(p_resultat.snitt_tallkar,'0.00')||                     |                                  ', snitt' ||to_char(p_resultat.snitt_tallkar,'0.00')||
                               ' Omfang: '||p_resultat.omfang ,p_loggnivaa);                                                                 ' Omfang: '||p_resultat.omfang ,p_loggnivaa);

    logg('På vitnemålet: Tallkarakterer: '||vm.antall_tallkarakterer||' stk., '||                                   logg('På vitnemålet: Tallkarakterer: '||vm.antall_tallkarakterer||' stk., '||
                                    'sum '||vm.sum_tallkarakterer||                                                                               'sum '||vm.sum_tallkarakterer||
                                ', snitt '||to_char(vm.snitt_tallkarakterer,'0.00')||                      |                                  ', snitt' ||to_char(vm.snitt_tallkarakterer,'0.00')||
                               ' Omfang: '||vm.omfang ,p_loggnivaa);                                                                         ' Omfang: '||vm.omfang ,p_loggnivaa);

    logg('Fordypninger ført (FF): '||p_resultat.fordypninger_foert, p_loggnivaa);                                  logg('Fordypninger ført (FF): '||p_resultat.fordypninger_foert, p_loggnivaa);

  end;                                                                                                          end;

  -- Merker av et fag som oppbrukt. Legger fagkoden bakerst med                                                 -- Merker av et fag som oppbrukt. Legger fagkoden bakerst med
  -- høyest nr i tabell oppbrukte_fag                                                                      |    -- høyest nr i tabell v_oppbrukte_fag
  procedure sett_oppbrukt (p_fagkode fag.fagkode%type) is                                                  |    procedure sett_oppbrukt (p_fagkode v_fag.fagkode%type) is
  begin                                                                                                         begin
    oppbrukte_fag_siste_nr := nvl(oppbrukte_fag_siste_nr,0) + 1;                                                  oppbrukte_fag_siste_nr := nvl(oppbrukte_fag_siste_nr,0) + 1;
    insert into oppbrukte_fag values (p_fagkode, oppbrukte_fag_siste_nr);                                  |      insert into v_oppbrukte_fag values (p_fagkode, oppbrukte_fag_siste_nr);
    logg('sett_oppbrukt '||p_fagkode||' ('||oppbrukte_fag_siste_nr||')', 8);                               |      logg('sett_oppbrukt '||p_fagkode||' (nr '||oppbrukte_fag_siste_nr||')', 8);
  end;                                                                                                          end;

  -- Gjør fag uoppbrukte igjen. Gjelder fagkodene i tabell                                                       -- Gjør fag uoppbrukte igjen. Gjelder fagkodene i tabell
  -- oppbrukte_fag med nr fra og med fom_nr til og med tom_nr                                                   -- oppbrukte_fag med nr fra og med fom_nr til og med tom_nr
  procedure ikke_oppbrukt (fom_nr number, tom_nr number default 9999) is                                        procedure ikke_oppbrukt (fom_nr number, tom_nr number default 9999) is
    fagliste varchar2(2000);                                                                                      fagliste varchar2(2000);
  begin                                                                                                         begin
  --  for fag in (select fagkode from oppbrukte_fag where nr between fom_nr and tom_nr)                    |      --for fag in (select fagkode from v_oppbrukte_fag where nr between fom_nr and tom_nr)
  --    loop fagliste := fagliste||' '||fag.fagkode; end loop;                                             |      --  loop fagliste := fagliste||' '||fag.fagkode; end loop;
    logg('ikke_oppbrukt '||fom_nr||' '||tom_nr||fagliste, 8);                                                     logg('ikke_oppbrukt '||fom_nr||' '||tom_nr||fagliste, 8);
    delete from oppbrukte_fag where nr between fom_nr and tom_nr;                                          |      delete from v_oppbrukte_fag where nr between fom_nr and tom_nr;
  end;                                                                                                          end;

  -- Bruker egen funksjon for divisjoner for å gi feilmelding                                                    -- Bruker egen funksjon for divisjoner for å gi feilmelding
  -- ved divisjon på 0.                                                                                          -- ved divisjon på 0.
  function divider (p1 number, p2 number, gierror number default 0)                                             function divider (p1 number, p2 number, gierror number default 0)
  return number is                                                                                              return number is
  begin                                                                                                         begin
    if p2 = 0 or p2 is null then  -- if nvl(p2,0)=0 then                                                          if p2 = 0 or p2 is null then  -- if nvl(p2,0)=0 then
      if gierror > 0 then error('Divisjon på 0!'); end if;                                                           if gierror > 0 then error('Divisjon på 0!'); end if;
      return 0;                                                                                                     return 0;
    else                                                                                                          else
      return p1/p2;                                                                                                 return p1/p2;
    end if;                                                                                                       end if;
  end;                                                                                                          end;

  -- Funksjonen get_vitnemaalfag kalles fra regn_ut_operand. Den                                                -- Funksjonen get_vitnemaalfag kalles fra regn_ut_operand. Den
  -- returnerer en record av samme type som en rad i tabell vitnemaalfag                                        -- returnerer en record av samme type som en rad i tabell vitnemaalfag
  -- dersom gitt fag p_fagkode finnes på gitt vitnemål p_vmnr, og det ikke                                        -- dersom gitt fag p_fagkode finnes på gitt vitnemål p_vmnr, og det ikke
  -- allerede er oppbrukt.                                                                                      -- allerede er oppbrukt. 
  --                                                                                                            --
  -- Faget må også være tatt som E (elev) eller P (privatist) dersom dette                                         -- Faget må også være tatt som E (elev) eller P (privatist) dersom dette
  -- kreves av p_attributtkode, som da vil være E eller P.                                                       -- kreves av p_attributtkode, som da vil være E eller P.
  --                                                                                                            --
  -- Gitt fag p_fagkode kan også være en såkallt generell fagkode, f.eks.                                          -- Gitt fag p_fagkode kan også være en såkallt generell fagkode, f.eks.
  -- AAXX20. Dersom f.eks. faget AA1020 da er på vitnemålet, og det ikke er                                       -- AAXX20. Dersom f.eks. faget AA1020 da er på vitnemålet, og det ikke er
  -- oppbrukt osv, returneres AA1020-raden fra vitnemaalfag herfra.                                             -- oppbrukt osv, returneres AA1020-raden fra vitnemaalfag herfra.
  -- XX betyr et tall fom 10 tom 19. AAYY33 betyr alle fag som starter                                          -- XX betyr et tall fom 10 tom 19. AAYY33 betyr alle fag som starter
  -- på AA og slutter på 33 og de to midterste er fom 19 tom 95.                                                  -- på AA og slutter på 33 og de to midterste er fom 19 tom 95.
  -- Altså: XX er 10-18, YY er 19-95.                                                                            -- Altså: XX er 10-18, YY er 19-95.
  --                                                                                                            --
  -- Dersom flere fag på vitnemålet passer til AAXX10, returneres det                                             -- Dersom flere fag på vitnemålet passer til AAXX10, returneres det
  -- første sortert alfanumerisk.                                                                                -- første sortert alfanumerisk.
  --                                                                                                            --
  -- Oracle-operatoren like sjekker om en streng passer i et mønster                                       |    -- Oracle-operatoren LIKE sjekker om en streng passer i et mønster
  -- der _ betyr hvilket som helst tegn.                                                                   |    -- der _ betyr et hvilket som helst tegn.

  function get_vitnemaalfag (                                                                                   function get_vitnemaalfag (
    p_vmnr            vitnemaalfag.vmnr%type,                                                              |      p_vmnr            v_vitnemaalfag.vmnr%type,
    p_operandtypekode vitnemaalfag.fagkode%type,                                                           |      p_operandtypekode v_vitnemaalfag.fagkode%type,
    p_fagkode         vitnemaalfag.fagkode%type,                                                           |      p_fagkode         v_vitnemaalfag.fagkode%type,
    p_attributtkode   attributt.attributtkode%type -- E eller P                                            |      p_attributtkode   v_attributt.attributtkode%type -- E eller P
  )                                                                                                             )
  return              vitnemaalfag%rowtype                                                                 |    return              v_vitnemaalfag%rowtype
  is                                                                                                            is
    vmfag             vitnemaalfag%rowtype;                                                                |      vmfag             v_vitnemaalfag%rowtype;
    to_midtre         varchar2(2);                                                                                to_midtre         varchar2(2);
    fagkodemoenster   varchar2(6);                                                                                fagkodemoenster   varchar2(6);
  begin                                                                                                         begin

    if p_operandtypekode = 'F' then                                                                               if p_operandtypekode = 'F' then
      begin                                                                                                         begin
        select * into vmfag from vitnemaalfag                                                              |          select * into vmfag from v_vitnemaalfag
        where vmnr = p_vmnr                                                                                           where vmnr = p_vmnr
        and fagkode=p_fagkode                                                                                         and fagkode=p_fagkode
        and ( nvl(p_attributtkode,'x') not in ('E','P') or nvl(privatistkode,'E') = p_attributtkode )                 and ( nvl(p_attributtkode,'x') not in ('E','P') or nvl(privatistkode,'E') = p_attributtkode )
        and not exists (select null from oppbrukte_fag where fagkode = p_fagkode);                         |          and not exists (select null from v_oppbrukte_fag where fagkode = p_fagkode);
      exception                                                                                                     exception
        when no_data_found then vmfag := null;                                                                        when no_data_found then vmfag := null;
      end;                                                                                                          end;

    elsif p_operandtypekode = 'G' then                                                                            elsif p_operandtypekode = 'G' then

      to_midtre := substr(p_fagkode,3,2);                                                                           to_midtre := substr(p_fagkode,3,2);
      fagkodemoenster := replace(replace(p_fagkode,'XX','__'),'YY','__');                                           fagkodemoenster := replace(replace(p_fagkode,'XX','__'),'YY','__');

      for vmf in (                                                                                                  for vmf in (
        select *                                                                                                      select *
        from vitnemaalfag                                                                                  |          from v_vitnemaalfag
        where vmnr = p_vmnr                                                                                           where vmnr = p_vmnr
        and (                                                                                                         and (
                fagkode=p_fagkode                                                                                             fagkode=p_fagkode
             or to_midtre='XX' and fagkode like fagkodemoenster and substr(fagkode,3,2) between '10' and '                 or to_midtre='XX' and fagkode like fagkodemoenster and substr(fagkode,3,2) between '10' and '
             or to_midtre='YY' and fagkode like fagkodemoenster and substr(fagkode,3,2) between '19' and '                 or to_midtre='YY' and fagkode like fagkodemoenster and substr(fagkode,3,2) between '19' and '
        )                                                                                                             )
        and ( nvl(p_attributtkode,'x') not in ('E','P') or nvl(privatistkode,'E') = p_attributtkode )                 and ( nvl(p_attributtkode,'x') not in ('E','P') or nvl(privatistkode,'E') = p_attributtkode )
        and fagkode not in (select fagkode from oppbrukte_fag)                                             |          and fagkode not in (select fagkode from v_oppbrukte_fag)
        order by fagkode                                                                                              order by fagkode
      )                                                                                                             )
      loop                                                                                                          loop
        -- vmfag blir det første funnede faget                                                                         -- vmfag blir det første funnede faget
        if vmfag.fagkode is null then                                                                                 if vmfag.fagkode is null then
          vmfag := vmf;                                                                                                 vmfag := vmf;
        end if;                                                                                                       end if;
      end loop;                                                                                                     end loop;

    elsif p_operandtypekode = 'X' then                                                                            elsif p_operandtypekode = 'X' then

      begin                                                                                                         begin
        fagkodemoenster := replace(p_fagkode,'XX','__');                                                              fagkodemoenster := replace(p_fagkode,'XX','__');
        select * into vmfag from vitnemaalfag                                                              |          select * into vmfag from v_vitnemaalfag
        where vmnr = p_vmnr                                                                                           where vmnr = p_vmnr
        and fagkode = (select min(fagkode) from vitnemaalfag                                               |          and fagkode = (select min(fagkode) from v_vitnemaalfag
                       where vmnr = p_vmnr                                                                                           where vmnr = p_vmnr
                       and fagkode like fagkodemoenster                                                                              and fagkode like fagkodemoenster
                       and fagkode not in (select fagkode from oppbrukte_fag));                            |                         and fagkode not in (select fagkode from v_oppbrukte_fag));
      exception                                                                                                     exception
        when no_data_found then vmfag := null;                                                                        when no_data_found then vmfag := null;
      end;                                                                                                          end;
    end if;                                                                                                       end if;

    return vmfag;                                                                                                 return vmfag;

  end;                                                                                                          end;

  -- Forward-/forhåndsdeklarasjon av kontroller_uttrykk. PL/SQL krever                                           -- Forward-/forhåndsdeklarasjon av kontroller_uttrykk. PL/SQL krever
  -- det siden kontroller_uttrykk og regn_ut_operand kaller hverandre.                                          -- det siden kontroller_uttrykk og regn_ut_operand kaller hverandre.
  function kontroller_uttrykk (                                                                                 function kontroller_uttrykk (
    p_vmnr              vitnemaal.vmnr%type,                                                               |      p_vmnr              v_vitnemaal.vmnr%type,
    p_kravversjonkode   kravuttrykk.kravversjonkode%type,                                                  |      p_kravversjonkode   v_kravuttrykk.kravversjonkode%type,
    p_kravuttrykknr     kravuttrykk.kravuttrykknr%type                                                     |      p_kravuttrykknr     v_kravuttrykk.kravuttrykknr%type
  ) return              resultattype;                                                                           ) return              resultattype;

  -- Funksjonen kalles fra kontroller_uttrykk med et gitt vitnemål,                                              -- Funksjonen kalles fra kontroller_uttrykk med et gitt vitnemål,
  -- kravversjonen og settet av variabler som utgjør operand1 eller 2.                                           -- kravversjonen og settet av variabler som utgjør operand1 eller 2.
  function regn_ut_operand (                                                        function regn_ut_operand (
    p_vmnr              vitnemaal.vmnr%type,                                                               |      p_vmnr              v_vitnemaal.vmnr%type,
    p_operandnr         number,                                                                                   p_operandnr         number,
    p_ku                kravuttrykk%rowtype                                                                |      p_ku                v_kravuttrykk%rowtype
  )                                                                                                             )
  return                resultattype                                                                            return                resultattype
  is                                                                                                            is
    -- operandverdiene                                                                                            -- operandverdiene
    o_operandtypekode   kravuttrykk.operandtypekode1%type;                                                 |      o_operandtypekode   v_kravuttrykk.operandtypekode1%type;
    o_kravuttrykknr     kravuttrykk.kravuttrykknr1%type;                                                   |      o_kravuttrykknr     v_kravuttrykk.kravuttrykknr1%type;
    o_fagkode           kravuttrykk.fagkode1%type;                                                         |      o_fagkode           v_kravuttrykk.fagkode1%type;
    o_attributtkode     kravuttrykk.attributtkode1%type;                                                   |      o_attributtkode     v_kravuttrykk.attributtkode1%type;
    o_konstant          kravuttrykk.konstant1%type;                                                        |      o_konstant          v_kravuttrykk.konstant1%type;

    resultat            resultattype;                                                                             resultat            resultattype;
    tmpresultat         resultattype;                                                                             tmpresultat         resultattype;
    obltrekkfag         fag.obltrekkfag%type;                                                              |      obltrekkfag         v_fag.obltrekkfag%type;
    vmfag               vitnemaalfag%rowtype;                                                              |      vmfag               v_vitnemaalfag%rowtype;
    omfang              number;                                                                                   omfang              number;
    konstant            number;                                                                                   konstant            number;
    ln                  number;                                                                                   ln                  number;

    karakter_standpunkt number;                                                                                   karakter_standpunkt number;
    karakter_eksamen    number;                                                                                   karakter_eksamen    number;
  begin                                                                                                         begin

    if p_operandnr = 1 then                                                                                       if p_operandnr = 1 then
      o_operandtypekode := p_ku.operandtypekode1;                                                                   o_operandtypekode := p_ku.operandtypekode1;
      o_kravuttrykknr   := p_ku.kravuttrykknr1;                                                                     o_kravuttrykknr   := p_ku.kravuttrykknr1;
      o_fagkode         := p_ku.fagkode1;                                                                           o_fagkode         := p_ku.fagkode1;
      o_attributtkode   := p_ku.attributtkode1;                                                                     o_attributtkode   := p_ku.attributtkode1;
      o_konstant        := p_ku.konstant1;                                                                          o_konstant        := p_ku.konstant1;
    else -- p_operandnr = 2                                                                                       else -- p_operandnr = 2
      o_operandtypekode := p_ku.operandtypekode2;                                                                   o_operandtypekode := p_ku.operandtypekode2;
      o_kravuttrykknr   := p_ku.kravuttrykknr2;                                                                     o_kravuttrykknr   := p_ku.kravuttrykknr2;
      o_fagkode         := p_ku.fagkode2;                                                                           o_fagkode         := p_ku.fagkode2;
      o_attributtkode   := p_ku.attributtkode2;                                                                     o_attributtkode   := p_ku.attributtkode2;
      o_konstant        := p_ku.konstant2;                                                                          o_konstant        := p_ku.konstant2;
    end if;                                                                                                       end if;

    if o_operandtypekode = 'U' then                                                                               if o_operandtypekode = 'U' then

      if skip_kravuttrykk.exists(o_kravuttrykknr) then                                                              if skip_kravuttrykk.exists(o_kravuttrykknr) then
        resultat := resultat_USANN;                                                                                   resultat := resultat_USANN;
        -- logg('Skipper '||o_kravuttrykknr, 4);                                                           |          logg('Skipper '||o_kravuttrykknr, 10);
      else                                                                                                          else
        resultat := kontroller_uttrykk(p_vmnr, p_ku.kravversjonkode, o_kravuttrykknr);                                resultat := kontroller_uttrykk(p_vmnr, p_ku.kravversjonkode, o_kravuttrykknr);
      end if;                                                                                                       end if;

    elsif o_operandtypekode in ('F','G','X') then                                                                 elsif o_operandtypekode in ('F','G','X') then

      -- Se kommentar på get_vitnemaalfag lenger opp...                                                              -- Se kommentar på get_vitnemaalfag lenger opp...
      vmfag := get_vitnemaalfag(p_vmnr, o_operandtypekode, o_fagkode, o_attributtkode);                             vmfag := get_vitnemaalfag(p_vmnr, o_operandtypekode, o_fagkode, o_attributtkode);

      if vmfag.fagkode is not null then                                                                             if vmfag.fagkode is not null then

        resultat := resultat_SANN;                                                                                    resultat := resultat_SANN;
        resultat.antall_fag              := 1;                                                                        resultat.antall_fag              := 1;
        select omfang into resultat.omfang from fag where fagkode=vmfag.fagkode;                           |          select nvl(omfang,0) into resultat.omfang from fag where fagkode=vmfag.fagkode;

        -- Skal regnr på karakterene som er varchar2(1) i basen, derfor:                                   |          -- Skal regne på karakterene som er varchar2(1) i basen, derfor:
        if vmfag.karakter_standpunkt between '0' and '6' then                                                         if vmfag.karakter_standpunkt between '0' and '6' then
          karakter_standpunkt := to_number(vmfag.karakter_standpunkt);                                                  karakter_standpunkt := to_number(vmfag.karakter_standpunkt);
          resultat.antall_tallkar := resultat.antall_tallkar + 1;                                                       resultat.antall_tallkar := resultat.antall_tallkar + 1;
          resultat.sum_tallkar := resultat.sum_tallkar + karakter_standpunkt;                                           resultat.sum_tallkar := resultat.sum_tallkar + karakter_standpunkt;
        else                                                                                                          else
          karakter_standpunkt := - ascii(vmfag.karakter_standpunkt);                                                    karakter_standpunkt := - ascii(vmfag.karakter_standpunkt);
        end if;                                                                                                       end if;

        if vmfag.karakter_eksamen between '0' and '6' then                                                            if vmfag.karakter_eksamen between '0' and '6' then
          karakter_eksamen := to_number(vmfag.karakter_eksamen);                                                        karakter_eksamen := to_number(vmfag.karakter_eksamen);
          resultat.antall_tallkar := resultat.antall_tallkar + 1;                                                       resultat.antall_tallkar := resultat.antall_tallkar + 1;
          resultat.sum_tallkar := resultat.sum_tallkar + karakter_eksamen;                                              resultat.sum_tallkar := resultat.sum_tallkar + karakter_eksamen;
        else                                                                                                          else
          karakter_eksamen := - ascii(vmfag.karakter_eksamen);                                                          karakter_eksamen := - ascii(vmfag.karakter_eksamen);
        end if;                                                                                                       end if;

        resultat.snitt_tallkar           := divider(resultat.sum_tallkar, resultat.antall_tallkar);                   resultat.snitt_tallkar           := divider(resultat.sum_tallkar, resultat.antall_tallkar);

        if vmfag.fordypningsfag = 'J' then                                                                            if vmfag.fordypningsfag = 'J' then
          resultat.fordypninger_foert    := 1;                                                                          resultat.fordypninger_foert    := 1;
        end if;                                                                                                       end if;

        -- Fra sist oppbrukte fag på vitnemålet:                                                                        -- Fra sist oppbrukte fag på vitnemålet:
        resultat.fagkode                 :=vmfag.fagkode;                                                             resultat.fagkode                 :=vmfag.fagkode;
        resultat.karakter_eksamen        :=karakter_eksamen;                                                          resultat.karakter_eksamen        :=karakter_eksamen;
        resultat.karakter_standpunkt     :=karakter_standpunkt;                                                       resultat.karakter_standpunkt     :=karakter_standpunkt;
--        resultat.obligatorisk_eksamen boolean; senere                                                       --        resultat.obligatorisk_eksamen boolean; senere
        resultat.privatistkode           :=vmfag.privatistkode;                                                       resultat.privatistkode           :=vmfag.privatistkode;

        sett_oppbrukt(vmfag.fagkode);                                                                                 sett_oppbrukt(vmfag.fagkode);

      -- Else faget er ikke på vitnemålet eller det er allerede oppbrukt                                              -- Else faget er ikke på vitnemålet eller det er allerede oppbrukt
      else                                                                                                          else
        resultat := resultat_USANN;                                                                                   resultat := resultat_USANN;
      end if;                                                                                                       end if;

    elsif o_operandtypekode = 'K' then                                                                            elsif o_operandtypekode = 'K' then

      resultat := resultat_SANN;                                                                                    resultat := resultat_SANN;
      resultat.resultattypekode          := 'T';                                                                    resultat.resultattypekode          := 'T';
      resultat.resultatkode              := null;                                                                   resultat.resultatkode              := null;
      resultat.resultattall              := o_konstant;                                                             resultat.resultattall              := o_konstant;

    elsif o_operandtypekode = 'V' then                                                                            elsif o_operandtypekode = 'V' then

      resultat := resultat_SANN;                                                                                    resultat := resultat_SANN;
      resultat.resultattypekode          := 'T';                                                                    resultat.resultattypekode          := 'T';
      resultat.resultatkode              := null;                                                                   resultat.resultatkode              := null;
      -- resultat.resultattall           := se under                                                                -- resultat.resultattall           := se under
      if o_attributtkode = 'ANTFAG' then                                                                            if o_attributtkode = 'ANTFAG' then
        select count(*)                                                                                               select count(*)
        into resultat.resultattall                                                                                    into resultat.resultattall
        from vitnemaalfag                                                                                  |          from v_vitnemaalfag
        where vmnr = p_vmnr;                                                                                          where vmnr = p_vmnr;
      else                                                                                                          else
        select nvl(decode(o_attributtkode,                                                                            select nvl(decode(o_attributtkode,
                         'OMFANG', omfang,                                                                                             'OMFANG', omfang,
                         'ANTTK',  antall_tallkarakterer,                                                                              'ANTTK',  antall_tallkarakterer,
                         'SUMTK',  sum_tallkarakterer,                                                                                 'SUMTK',  sum_tallkarakterer,
                         'SNTTK',  snitt_tallkarakterer,                                                                               'SNTTK',  snitt_tallkarakterer,
                         'FORDP',  fordypningspoeng1,                                                                                  'FORDP',  fordypningspoeng1,
                         'REALFP', fordypningspoeng2,                                                                                  'REALFP', fordypningspoeng2,
                         0), 0)                                                                                                        0), 0)
        into resultat.resultattall                                                                                    into resultat.resultattall
        from vitnemaal                                                                                     |          from v_vitnemaal
        where vmnr = p_vmnr;                                                                                          where vmnr = p_vmnr;
      end if;                                                                                                       end if;

    elsif o_operandtypekode = 'D' then                                                                            elsif o_operandtypekode = 'D' then

      resultat := denne;                                                                                            resultat := denne;

    else                                                                                                          else

      error('o_operandtypekode="'||o_operandtypekode||'",  verken U, F, G, K, V eller D');                          error('o_operandtypekode="'||o_operandtypekode||'",  verken U, F, G, K, V eller D');

    end if;                                                                                                       end if;

    if o_attributtkode is not null and o_operandtypekode <> 'V' then                                              if o_attributtkode is not null and o_operandtypekode <> 'V' then
      if o_konstant is not null then                                                                                if o_konstant is not null then
        if resultat.resultatkode = 'SANN' then                                                                        if resultat.resultatkode = 'SANN' then

          if o_konstant <= -10000 then                                                                                  if o_konstant <= -10000 then
             if resultat.antall_fag > 0 then                                                                               if resultat.antall_fag > 0 then
               denne := resultat;                                                                                            denne := resultat;
             end if;                                                                                                       end if;
             tmpresultat := kontroller_uttrykk(p_vmnr, p_ku.kravversjonkode, - o_konstant - 10000);                        tmpresultat := kontroller_uttrykk(p_vmnr, p_ku.kravversjonkode, - o_konstant - 10000);
             if tmpresultat.resultattypekode = 'T' then                                                                    if tmpresultat.resultattypekode = 'T' then
               konstant := tmpresultat.resultattall;                                                                         konstant := tmpresultat.resultattall;
             else                                                                                                          else
               error('Attributtilordningsverdiutregning ga ikke tall. Knr='||(-o_konstant-10000));                           error('Attributtilordningsverdiutregning ga ikke tall. Knr='||(-o_konstant-10000));
             end if;                                                                                                       end if;
          else                                                                                                          else
            konstant := o_konstant;                                                                                       konstant := o_konstant;
          end if;                                                                                                       end if;

          if    o_attributtkode='ANTFAG' then resultat.antall_fag          := konstant;                                 if    o_attributtkode='ANTFAG' then resultat.antall_fag          := konstant;
          elsif o_attributtkode='OMFANG' then resultat.omfang              := konstant;                                 elsif o_attributtkode='OMFANG' then resultat.omfang              := konstant;
          elsif o_attributtkode='VEKT'   then resultat.vekt                := konstant;                                 elsif o_attributtkode='VEKT'   then resultat.vekt                := konstant;
          elsif o_attributtkode='ANTTK'  then resultat.antall_tallkar      := konstant;                                 elsif o_attributtkode='ANTTK'  then resultat.antall_tallkar      := konstant;
          elsif o_attributtkode='SUMTK'  then resultat.sum_tallkar         := konstant;                                 elsif o_attributtkode='SUMTK'  then resultat.sum_tallkar         := konstant;
          elsif o_attributtkode='SNTTK'  then resultat.snitt_tallkar       := konstant;                                 elsif o_attributtkode='SNTTK'  then resultat.snitt_tallkar       := konstant;
          elsif o_attributtkode='SKAR'   then resultat.karakter_standpunkt := konstant;                                 elsif o_attributtkode='SKAR'   then resultat.karakter_standpunkt := konstant;
          elsif o_attributtkode='EKAR'   then resultat.karakter_eksamen    := konstant;                                 elsif o_attributtkode='EKAR'   then resultat.karakter_eksamen    := konstant;
          elsif o_attributtkode='ANTFF'  then resultat.fordypninger_foert  := konstant;                                 elsif o_attributtkode='ANTFF'  then resultat.fordypninger_foert  := konstant;
          end if;                                                                                                       end if;
        end if;                                                                                                       end if;
      elsif o_attributtkode not in ('E','P') then                                                          |        elsif o_attributtkode not in ('E','P')
                                                                                                           >        and not (resultat.resultattypekode = 'B' and resultat.resultatkode = 'USANN') then
        resultat.resultattypekode:='T';                                                                               resultat.resultattypekode:='T';
        resultat.resultatkode:=null;                                                                                  resultat.resultatkode:=null;
        if    o_attributtkode='ANTFAG' then resultat.resultattall   := resultat.antall_fag;                           if    o_attributtkode='ANTFAG' then resultat.resultattall   := resultat.antall_fag;
        elsif o_attributtkode='OMFANG' then resultat.resultattall   := resultat.omfang;                               elsif o_attributtkode='OMFANG' then resultat.resultattall   := resultat.omfang;
        elsif o_attributtkode='VEKT'   then resultat.resultattall   := resultat.vekt;                                 elsif o_attributtkode='VEKT'   then resultat.resultattall   := resultat.vekt;
        elsif o_attributtkode='ANTTK'  then resultat.resultattall   := resultat.antall_tallkar;                       elsif o_attributtkode='ANTTK'  then resultat.resultattall   := resultat.antall_tallkar;
        elsif o_attributtkode='SUMTK'  then resultat.resultattall   := resultat.sum_tallkar;                          elsif o_attributtkode='SUMTK'  then resultat.resultattall   := resultat.sum_tallkar;
        elsif o_attributtkode='SNTTK'  then resultat.resultattall   := resultat.snitt_tallkar;                        elsif o_attributtkode='SNTTK'  then resultat.resultattall   := resultat.snitt_tallkar;
        elsif o_attributtkode='SKAR'   then resultat.resultattall   := resultat.karakter_standpunkt;                  elsif o_attributtkode='SKAR'   then resultat.resultattall   := resultat.karakter_standpunkt;
        elsif o_attributtkode='EKAR'   then resultat.resultattall   := resultat.karakter_eksamen;                     elsif o_attributtkode='EKAR'   then resultat.resultattall   := resultat.karakter_eksamen;
        elsif o_attributtkode='ANTFF'  then resultat.resultattall   := resultat.fordypninger_foert;                   elsif o_attributtkode='ANTFF'  then resultat.resultattall   := resultat.fordypninger_foert;
        end if;                                                                                                       end if;
      end if;                                                                                                       end if;
    end if;                                                                                                       end if;

    if resultat.antall_fag > 0 then                                                                               if resultat.antall_fag > 0 then
      denne := resultat;                                                                                            denne := resultat;
    end if;                                                                                                       end if;

    if o_operandtypekode = 'D' then                                                                               if o_operandtypekode = 'D' then
      tmpresultat := resultat;                                                                                      tmpresultat := resultat;
      resultat := resultat_SANN;                                                                                    resultat := resultat_SANN;
      resultat.resultattypekode := tmpresultat.resultattypekode;                                                    resultat.resultattypekode := tmpresultat.resultattypekode;
      resultat.resultatkode     := tmpresultat.resultatkode;                                                        resultat.resultatkode     := tmpresultat.resultatkode;
      resultat.resultattall     := tmpresultat.resultattall;                                                        resultat.resultattall     := tmpresultat.resultattall;
    end if;                                                                                                       end if;

    if resultat.resultattypekode = 'B' and resultat.resultatkode = 'SANN'                                         if resultat.resultattypekode = 'B' and resultat.resultatkode = 'SANN'
    then ln := 8; else ln := 9; end if;                                                                           then ln := 8; else ln := 9; end if;

    logg('       Resultat '          ||                                                                           logg('       Resultat '          ||
         p_operandnr                 ||' = '||                                                                         p_operandnr                 ||' = '||
         resultat.resultattypekode   ||', '||                                                                          resultat.resultattypekode   ||', '||
         resultat.resultatkode       ||', '||                                                                          resultat.resultatkode       ||', '||
         resultat.resultattall       ||' ('||                                                                          resultat.resultattall       ||' ('||
         resultat.antall_fag         ||','||                                                                           resultat.antall_fag         ||','||
         resultat.omfang             ||','||                                                                           resultat.omfang             ||','||
         resultat.vekt               ||','||                                                                           resultat.vekt               ||','||
         resultat.antall_tallkar     ||','||                                                                           resultat.antall_tallkar     ||','||
         resultat.sum_tallkar        ||','||                                                                           resultat.sum_tallkar        ||','||
         resultat.snitt_tallkar      ||','||                                                                           resultat.snitt_tallkar      ||','||
         resultat.fordypninger_foert ||')'                                                                             resultat.fordypninger_foert ||')'
    ,ln                                                                                                           ,ln
    );                                                                                                            );

    return resultat;                                                                                              return resultat;

  end regn_ut_operand;                                                                                          end regn_ut_operand;

  function regn_ut_samme (                                                                                      function regn_ut_samme (
    p_vmnr              vitnemaal.vmnr%type,                                                               |      p_vmnr              v_vitnemaal.vmnr%type,
    p_ku                kravuttrykk%rowtype                                                                |      p_ku                v_kravuttrykk%rowtype
  )                                                                                                             )
  return                resultattype                                                                            return                resultattype
  is                                                                                                            is
    test_fagkode        fag.fagkode%type;                                                                  |      test_fagkode        v_fag.fagkode%type;
    resultat            resultattype;                                                                             resultat            resultattype;
    operand             kravuttrykk%rowtype;                                                               |      operand             v_kravuttrykk%rowtype;
  begin                                                                                                         begin

    -- Løper gjennom oppbrukte fagkoder som passer den generelle fagkoden                                          -- Løper gjennom oppbrukte fagkoder som passer den generelle fagkoden
    -- i operand 2 i kravuttrykket                                                                                -- i operand 2 i kravuttrykket
    for par2 in (                                                                                                 for par2 in (
      select fagkode from oppbrukte_fag                                                                    |        select fagkode from v_oppbrukte_fag
      where fagkode like replace(replace(p_ku.fagkode2,'XX','__'),'YY','__')                                        where fagkode like replace(replace(p_ku.fagkode2,'XX','__'),'YY','__')
      and(                                                                                                          and(
             (substr(p_ku.fagkode2,3,2)='XX' and to_number(substr(fagkode,3,2)) between 10 and 18)                         (substr(p_ku.fagkode2,3,2)='XX' and to_number(substr(fagkode,3,2)) between 10 and 18)
          or (substr(p_ku.fagkode2,3,2)='YY' and to_number(substr(fagkode,3,2)) between 19 and 95)                      or (substr(p_ku.fagkode2,3,2)='YY' and to_number(substr(fagkode,3,2)) between 19 and 95)
          or (substr(p_ku.fagkode2,3,2) not in ('XX','YY'))                                                             or (substr(p_ku.fagkode2,3,2) not in ('XX','YY'))
      )                                                                                                             )
      order by fagkode                                                                                              order by fagkode
    )                                                                                                             )
    loop                                                                                                          loop
      -- ...og finner den første sanne som passer til operand 1 i kravuttrykket                                      -- ...og finner den første sanne som passer til operand 1 i kravuttrykket
      if nvl(resultat.resultatkode,'x')<>'SANN' then                                                                if nvl(resultat.resultatkode,'x')<>'SANN' then
        -- Setter test_fagkode lik p_kravuttrykk.fagkode1, men der XX eller YY byttes                                 -- Setter test_fagkode lik p_kravuttrykk.fagkode1, men der XX eller YY byttes 
        -- med tallet i tilsvarende posisjon som XX/YY i current oppbrukte fagkode                                    -- med tallet i tilsvarende posisjon som XX/YY i current oppbrukte fagkode
        test_fagkode := p_ku.fagkode1;                                                                                test_fagkode := p_ku.fagkode1;
        if substr(test_fagkode,3,2) in ('XX','YY') then                                                               if substr(test_fagkode,3,2) in ('XX','YY') then
          test_fagkode := substr(test_fagkode,1,2)||substr(par2.fagkode,3,2)||substr(test_fagkode,5,2);                 test_fagkode := substr(test_fagkode,1,2)||substr(par2.fagkode,3,2)||substr(test_fagkode,5,2);
        end if;                                                                                                       end if;
        operand := p_ku;                                                                                              operand := p_ku;
        operand.operandtypekode1 := 'F';                                                                              operand.operandtypekode1 := 'F';
        operand.fagkode1         := test_fagkode;                                                                     operand.fagkode1         := test_fagkode;

        resultat := regn_ut_operand(p_vmnr, 1, operand);                                                              resultat := regn_ut_operand(p_vmnr, 1, operand);

      end if;                                                                                                       end if;
    end loop;                                                                                                     end loop;
    if resultat.resultattypekode is null then                                                                     if resultat.resultattypekode is null then
      resultat := resultat_USANN;                                                                                   resultat := resultat_USANN;
    end if;                                                                                                       end if;
    return resultat;                                                                                              return resultat;
  end regn_ut_samme;                                                                                            end regn_ut_samme;

  -- Funksjon kontroller_uttrykk virker på et vitnemål og en rad i kontroll-tabellen.                             -- Funksjon kontroller_uttrykk virker på et vitnemål og en rad i kontroll-tabellen.
  -- Den består av tre deler:                                                                                    -- Den består av tre deler:
  -- Del 1: Regn ut resultat av operand 1                                                                       -- Del 1: Regn ut resultat av operand 1  
  -- Del 2: Regn ut resultat av operand 2                                                                       -- Del 2: Regn ut resultat av operand 2
  -- Del 3: Regn ut og returner resultatet av kontrollraden.                                                    -- Del 3: Regn ut og returner resultatet av kontrollraden.
  --        D.v.s. resultat1 OPERATOR resultat2.                                                                --        D.v.s. resultat1 OPERATOR resultat2.

  function kontroller_uttrykk (                                                     function kontroller_uttrykk (
    p_vmnr             vitnemaal.vmnr%type,                                                                |      p_vmnr             v_vitnemaal.vmnr%type,
    p_kravversjonkode  kravuttrykk.kravversjonkode%type,                                                   |      p_kravversjonkode  v_kravuttrykk.kravversjonkode%type,
    p_kravuttrykknr    kravuttrykk.kravuttrykknr%type                                                      |      p_kravuttrykknr    v_kravuttrykk.kravuttrykknr%type
  ) return             resultattype                                                                             ) return             resultattype
  is                                                                                                            is
    resultat1          resultattype;                                                                              resultat1          resultattype;
    resultat2          resultattype;                                                                              resultat2          resultattype;
    res_alle           resultattype;                                                                              res_alle           resultattype;
    resultat           resultattype;                                                                              resultat           resultattype;
    denne_tmp          resultattype;                                                                              denne_tmp          resultattype;

    nr1                number := null;      -- oppbrukte_fag_siste_nr før operand 1                        |      nr1                number := null;        -- oppbrukte_fag_siste_nr før operand 1
    nr2                number := null;      -- oppbrukte_fag_siste_nr før operand 2 (eller før alle)       |      nr2                number := null;        -- oppbrukte_fag_siste_nr før operand 2 (eller før alle)
    ku                 kravuttrykk%rowtype; -- en rad i kontrolltabellen                                   |      ku                 v_kravuttrykk%rowtype; -- en rad i kontrolltabellen
    boo                boolean;                                                                                   boo                boolean;
    kravuttrykknr_forrige number;                                                                                 kravuttrykknr_forrige number;
    loggnivaa_forrige     number;                                                                                 loggnivaa_forrige     number;
    kk                 string(80);                                                                                kk                 string(80);
  begin                                                                                                         begin

    kravuttrykknr_forrige := kravuttrykknr_current;                                                               kravuttrykknr_forrige := kravuttrykknr_current;
    kravuttrykknr_current := p_kravuttrykknr;                                                                     kravuttrykknr_current := p_kravuttrykknr;

    -- Kanskje overskriftmeldinger finnes?                                                                        -- Kanskje overskriftmeldinger finnes?
    logg_melding(p_kravversjonkode, p_kravuttrykknr, resultat, 9999, kravuttrykknr_forrige);                      logg_melding(p_kravversjonkode, p_kravuttrykknr, resultat, 9999, kravuttrykknr_forrige);

    -- setter record ku til raden i krauttrykk som man ser på nå                                                    -- setter record ku til raden i krauttrykk som man ser på nå
    select * into ku from kravuttrykk                                                                             select * into ku from kravuttrykk
    where kravversjonkode=p_kravversjonkode                                                                       where kravversjonkode=p_kravversjonkode
    and kravuttrykknr = p_kravuttrykknr;                                                                          and kravuttrykknr = p_kravuttrykknr;

    -- Finner evt kravdefinisjonbestemt loggenivå                                                                  -- Finner evt kravdefinisjonbestemt loggenivå
    loggnivaa_forrige := loggnivaa_current;                                                                       loggnivaa_forrige := loggnivaa_current;
    if loggnivaa.exists(p_kravuttrykknr) then                                                                     if loggnivaa.exists(p_kravuttrykknr) then
      loggnivaa_current := loggnivaa(p_kravuttrykknr);                                                              loggnivaa_current := loggnivaa(p_kravuttrykknr);
    end if;                                                                                                       end if;

    -- Logger kravuttrykk-raden                                                                                   -- Logger kravuttrykk-raden
    if kravkode.exists(p_kravuttrykknr) then                                                                      if kravkode.exists(p_kravuttrykknr) then
      kk:=kravkode(p_kravuttrykknr);                                                                                kk:=kravkode(p_kravuttrykknr);
    else                                                                                                          else
      kk:=null;                                                                                                     kk:=null;
    end if;                                                                                                       end if;
    logg(rpad(ku.operatorkode     ,7)||                                                                           logg(rpad(ku.operatorkode     ,7)||

         rpad(ku.operandtypekode1 ,2)||                                                                                rpad(ku.operandtypekode1 ,2)||
         rpad(ku.kravuttrykknr1   ,5)||                                                                                rpad(ku.kravuttrykknr1   ,5)||
         rpad(ku.fagkode1         ,7)||                                                                                rpad(ku.fagkode1         ,7)||
         rpad(ku.attributtkode1   ,7)||                                                                                rpad(ku.attributtkode1   ,7)||
         rpad(ku.konstant1        ,8)||                                                                                rpad(ku.konstant1        ,8)||

         rpad(ku.operandtypekode2 ,2)||                                                                                rpad(ku.operandtypekode2 ,2)||
         rpad(ku.kravuttrykknr2   ,5)||                                                                                rpad(ku.kravuttrykknr2   ,5)||
         rpad(ku.fagkode2         ,7)||                                                                                rpad(ku.fagkode2         ,7)||
         rpad(ku.attributtkode2   ,7)||                                                                                rpad(ku.attributtkode2   ,7)||
         rpad(ku.konstant2        ,8)||                                                                                rpad(ku.konstant2        ,8)||

         kk                                                                                                            kk
     ,7                                                                                                            ,7
    );                                                                                                            );

    -- ---------- DEL 1, UTREGNING AV OPERAND 1 ----------                                                        -- ---------- DEL 1, UTREGNING AV OPERAND 1 ----------
    nr1 := nvl(oppbrukte_fag_siste_nr,0);                                                                         nr1 := nvl(oppbrukte_fag_siste_nr,0);

    -- HELE ... SAMME ...                                                                                         -- HELE ... SAMME ...
    if ku.operatorkode = 'HELE' then                                                                              if ku.operatorkode = 'HELE' then
      ikke_oppbrukt(0);                                                                                             ikke_oppbrukt(0);
      denne := resultat_USANN;                                                                                      denne := resultat_USANN;
    elsif ku.operatorkode = 'SAMME' then                                                                          elsif ku.operatorkode = 'SAMME' then
      resultat := regn_ut_samme(p_vmnr, ku);                                                                        resultat := regn_ut_samme(p_vmnr, ku);
      if resultat.antall_fag > 0 then                                                                               if resultat.antall_fag > 0 then
        denne := resultat;                                                                                            denne := resultat;
      end if;                                                                                                       end if;
      logg_melding(p_kravversjonkode, p_kravuttrykknr, resultat, nr1+1);                                            logg_melding(p_kravversjonkode, p_kravuttrykknr, resultat, nr1+1);
      kravuttrykknr_current := kravuttrykknr_forrige;                                                               kravuttrykknr_current := kravuttrykknr_forrige;
      loggnivaa_current := loggnivaa_forrige;                                                                       loggnivaa_current := loggnivaa_forrige;
      return resultat;                                                                                              return resultat;
    end if;                                                                                                       end if;

    resultat1 := regn_ut_operand(p_vmnr, 1, ku);                                                                  resultat1 := regn_ut_operand(p_vmnr, 1, ku);

    nr2 := nvl(oppbrukte_fag_siste_nr,0);                                                                         nr2 := nvl(oppbrukte_fag_siste_nr,0);
    if ku.operatorkode = 'ALLE' and resultat1.resultatkode = 'SANN'                                               if ku.operatorkode = 'ALLE' and resultat1.resultatkode = 'SANN'
    then                                                                                                          then

      denne_tmp := denne;                                                                                           denne_tmp := denne;
      res_alle := kontroller_uttrykk(p_vmnr,                                                                        res_alle := kontroller_uttrykk(p_vmnr,
                                     p_kravversjonkode,                                                                                            p_kravversjonkode,
                                     p_kravuttrykknr);                                                                                             p_kravuttrykknr);
      denne := denne_tmp;                                                                                           denne := denne_tmp;
      logg('      res_alle = '||res_alle.resultattypekode||', '||                                                   logg('      res_alle = '||res_alle.resultattypekode||', '||
                                res_alle.resultatkode||', '||                                                                                 res_alle.resultatkode||', '||
                                res_alle.resultattall||', '||                                                                                 res_alle.resultattall||', '||
                                res_alle.vekt,9);                                                                                             res_alle.vekt,9);
      logg(resultat1.resultatkode||'  '||ku.operatorkode,9);                                                        logg(resultat1.resultatkode||'  '||ku.operatorkode,9);

    end if;                                                                                                       end if;

    -- Kanskje operand 2 ikke behøver å regnes ut?                                                                  -- Kanskje operand 2 ikke behøver å regnes ut?
    -- Returner resultatet av operand 1 isåfall.                                                                   -- Returner resultatet av operand 1 isåfall.
    if resultat1.resultatkode = 'SANN'  and ku.operatorkode = 'ELLER'                                             if resultat1.resultatkode = 'SANN'  and ku.operatorkode = 'ELLER'
    or resultat1.resultatkode = 'USANN' and ku.operatorkode in ('OG','ALLE','FØRSTE')                              or resultat1.resultatkode = 'USANN' and ku.operatorkode in ('OG','ALLE','FØRSTE')
    or ku.operatorkode in ('HELE','DUMMY')                                                                        or ku.operatorkode in ('HELE','DUMMY')
    then                                                                                                          then
      if resultat1.antall_fag > 0 then denne := resultat1; end if;                                                  if resultat1.antall_fag > 0 then denne := resultat1; end if;
      logg_melding(p_kravversjonkode, p_kravuttrykknr, resultat1, nr1+1, kravuttrykknr_forrige);                    logg_melding(p_kravversjonkode, p_kravuttrykknr, resultat1, nr1+1, kravuttrykknr_forrige);
      if ku.operatorkode = 'HELE' then                                                                              if ku.operatorkode = 'HELE' then
        if kravkode.exists(p_kravuttrykknr) then kk := kravkode(p_kravuttrykknr); else kk := null; end if;            if kravkode.exists(p_kravuttrykknr) then kk := kravkode(p_kravuttrykknr); else kk := null; end if;
        logg_sluttrapport(p_vmnr, resultat1, p_kravversjonkode, kk, 6);                                               logg_sluttrapport(p_vmnr, resultat1, p_kravversjonkode, kk, 6);
      end if;                                                                                                       end if;
      kravuttrykknr_current := kravuttrykknr_forrige;                                                               kravuttrykknr_current := kravuttrykknr_forrige;
      loggnivaa_current := loggnivaa_forrige;                                                                       loggnivaa_current := loggnivaa_forrige;
      return resultat1;                                                                                             return resultat1;
    end if;                                                                                                       end if;

    -- ---------- DEL 2, UTREGNING AV OPERAND 2 ----------                                                        -- ---------- DEL 2, UTREGNING AV OPERAND 2 ----------

    if ku.operatorkode in ('ALLE','FØRSTE') and ku.operandtypekode2 is null then                                   if ku.operatorkode in ('ALLE','FØRSTE') and ku.operandtypekode2 is null then

      resultat2 := resultat_SANN;                                                                                   resultat2 := resultat_SANN;

    else                                                                                                          else

      resultat2 := regn_ut_operand(p_vmnr, 2, ku);                                                                  resultat2 := regn_ut_operand(p_vmnr, 2, ku);

    end if;                                                                                                       end if;

    -- ---------- DEL 3, FINN RESULTAT V.H.A. OPERATOR OG RESULTAT AV OPERAND 1 OG 2 ----------                   -- ---------- DEL 3, FINN RESULTAT V.H.A. OPERATOR OG RESULTAT AV OPERAND 1 OG 2 ----------

    -- Hvis resultat1 og 2 er B (boolsk) ==> Lager boolsk resultat                                                -- Hvis resultat1 og 2 er B (boolsk) ==> Lager boolsk resultat

    if  resultat1.resultattypekode = 'B'                                                                          if  resultat1.resultattypekode = 'B'
    and resultat2.resultattypekode = 'B' then                                                                     and resultat2.resultattypekode = 'B' then

      if ku.operatorkode in ('ELLER','ELLERF') and resultat1.resultatkode = 'USANN' then                            if ku.operatorkode in ('ELLER','ELLERF') and resultat1.resultatkode = 'USANN' then
        resultat := resultat2;                                                                                        resultat := resultat2;
      elsif ku.operatorkode = 'ELLERF' and resultat2.resultatkode = 'USANN' then                                    elsif ku.operatorkode = 'ELLERF' and resultat2.resultatkode = 'USANN' then
        resultat := resultat1;                                                                                        resultat := resultat1;
      elsif ku.operatorkode = 'ALLE' and resultat2.resultatkode = 'USANN' then                                      elsif ku.operatorkode = 'ALLE' and resultat2.resultatkode = 'USANN' then
        resultat := res_alle;                                                                                         resultat := res_alle;
        ikke_oppbrukt(nr1 + 1, nr2);                                                                                  ikke_oppbrukt(nr1 + 1, nr2);
      elsif ku.operatorkode = 'FØRSTE' and resultat2.resultatkode = 'SANN' then                            |  --      elsif ku.operatorkode = 'FØRSTE' and resultat2.resultatkode = 'SANN' then
        resultat := resultat1;                                                                             |  --        resultat := resultat1;
        -- ikke_oppbrukt(nr2 + 1);                                                                         |  --        -- ikke_oppbrukt(nr2 + 1);
      elsif ku.operatorkode = 'FØRSTE' and resultat2.resultatkode = 'USANN' then                                     elsif ku.operatorkode = 'FØRSTE' and resultat2.resultatkode = 'USANN' then
        resultat := kontroller_uttrykk(p_vmnr,                                                                        resultat := kontroller_uttrykk(p_vmnr,
                                       p_kravversjonkode,                                                                                            p_kravversjonkode,
                                       p_kravuttrykknr);                                                                                             p_kravuttrykknr);
        ikke_oppbrukt(nr1 + 1, nr2);                                                                                  ikke_oppbrukt(nr1 + 1, nr2);
      elsif ku.operatorkode = 'OG' and resultat2.resultatkode = 'USANN' then                                        elsif ku.operatorkode = 'OG' and resultat2.resultatkode = 'USANN' then
        resultat := resultat2;                                                                                        resultat := resultat2;
        ikke_oppbrukt(nr1 + 1);                                                                                       ikke_oppbrukt(nr1 + 1);
      else                                                                                                          else
        -- Situasjonen er nå to sanne operander og operator er OG, ELLERF eller ALLE.                      |          -- Situasjonen er nå to sanne operander og operator er OG, ELLERF, ALLE eller FØRSTE
        -- Summerer opp i operand 2 og returnerer den.                                                     |          -- (Tester dette for sikkerhets skyld i første IF under)
                                                                                                           >          -- Summerer dermed resultat := resultat1 "+" resultat2 "+" evt res_alle,
                                                                                                           >          -- og returnerer resultat.

        if ku.operatorkode not in ('OG','ELLERF','ALLE') then                                              |          if ku.operatorkode not in ('OG','ELLERF','ALLE','FØRSTE') then
          error('Skal aldri se dette! Operator='||ku.operatorkode);                                                     error('Skal aldri se dette! Operator='||ku.operatorkode);
        end if;                                                                                                       end if;

        resultat := resultat2;                                                                                        resultat := resultat2;

        resultat.antall_fag         := resultat1.antall_fag      + resultat2.antall_fag;                              resultat.antall_fag         := resultat1.antall_fag      + resultat2.antall_fag;
        resultat.omfang             := resultat1.omfang          + resultat2.omfang;                                  resultat.omfang             := resultat1.omfang          + resultat2.omfang;
        resultat.vekt               := resultat1.vekt            + resultat2.vekt;                                    resultat.vekt               := resultat1.vekt            + resultat2.vekt;
        resultat.antall_tallkar     := resultat1.antall_tallkar  + resultat2.antall_tallkar;                          resultat.antall_tallkar     := resultat1.antall_tallkar  + resultat2.antall_tallkar;
        resultat.sum_tallkar        := resultat1.sum_tallkar     + resultat2.sum_tallkar;                             resultat.sum_tallkar        := resultat1.sum_tallkar     + resultat2.sum_tallkar;
        resultat.snitt_tallkar      := divider(resultat.sum_tallkar, resultat.antall_tallkar);                        resultat.snitt_tallkar      := divider(resultat.sum_tallkar, resultat.antall_tallkar);
        resultat.fordypninger_foert := resultat1.fordypninger_foert + resultat2.fordypninger_foert;                   resultat.fordypninger_foert := resultat1.fordypninger_foert + resultat2.fordypninger_foert;

        if resultat2.fagkode is not null then                                                                         if resultat2.fagkode is not null then
          resultat.fagkode              := resultat2.fagkode;                                                           resultat.fagkode              := resultat2.fagkode;
          resultat.karakter_eksamen     := resultat2.karakter_eksamen;                                                  resultat.karakter_eksamen     := resultat2.karakter_eksamen;
          resultat.karakter_standpunkt  := resultat2.karakter_standpunkt;                                               resultat.karakter_standpunkt  := resultat2.karakter_standpunkt;
          resultat.obligatorisk_eksamen := resultat2.obligatorisk_eksamen;                                              resultat.obligatorisk_eksamen := resultat2.obligatorisk_eksamen;
          resultat.privatistkode        := resultat2.privatistkode;                                                     resultat.privatistkode        := resultat2.privatistkode;
        else                                                                                                          else
          resultat.fagkode              := resultat1.fagkode;                                                           resultat.fagkode              := resultat1.fagkode;
          resultat.karakter_eksamen     := resultat1.karakter_eksamen;                                                  resultat.karakter_eksamen     := resultat1.karakter_eksamen;
          resultat.karakter_standpunkt  := resultat1.karakter_standpunkt;                                               resultat.karakter_standpunkt  := resultat1.karakter_standpunkt;
          resultat.obligatorisk_eksamen := resultat1.obligatorisk_eksamen;                                              resultat.obligatorisk_eksamen := resultat1.obligatorisk_eksamen;
          resultat.privatistkode        := resultat1.privatistkode;                                                     resultat.privatistkode        := resultat1.privatistkode;
        end if;                                                                                                       end if;

        if ku.operatorkode = 'ALLE' then                                                                              if ku.operatorkode = 'ALLE' then
          resultat.antall_fag         := resultat.antall_fag       + res_alle.antall_fag;                               resultat.antall_fag         := resultat.antall_fag       + res_alle.antall_fag;
          resultat.omfang             := resultat.omfang           + res_alle.omfang;                                   resultat.omfang             := resultat.omfang           + res_alle.omfang;
          resultat.vekt               := resultat.vekt             + res_alle.vekt;                                     resultat.vekt               := resultat.vekt             + res_alle.vekt;
          resultat.antall_tallkar     := resultat.antall_tallkar   + res_alle.antall_tallkar;                           resultat.antall_tallkar     := resultat.antall_tallkar   + res_alle.antall_tallkar;
          resultat.sum_tallkar        := resultat.sum_tallkar      + res_alle.sum_tallkar;                              resultat.sum_tallkar        := resultat.sum_tallkar      + res_alle.sum_tallkar;
          resultat.snitt_tallkar      := divider(resultat.sum_tallkar, resultat.antall_tallkar);                        resultat.snitt_tallkar      := divider(resultat.sum_tallkar, resultat.antall_tallkar);
          resultat.fordypninger_foert := resultat.fordypninger_foert + res_alle.fordypninger_foert;                     resultat.fordypninger_foert := resultat.fordypninger_foert + res_alle.fordypninger_foert;
        end if;                                                                                                       end if;
      end if;                                                                                                       end if;

    elsif resultat1.resultattypekode = 'T'                                                                        elsif resultat1.resultattypekode = 'T'
    and   resultat2.resultattypekode = 'T' then                                                                   and   resultat2.resultattypekode = 'T' then

      resultat := resultat2;                                                                                        resultat := resultat2;

      if    ku.operatorkode='ADD' then resultat.resultattall := resultat1.resultattall + resultat2.resulta          if    ku.operatorkode='ADD' then resultat.resultattall := resultat1.resultattall + resultat2.resulta
      elsif ku.operatorkode='SUB' then resultat.resultattall := resultat1.resultattall - resultat2.resulta          elsif ku.operatorkode='SUB' then resultat.resultattall := resultat1.resultattall - resultat2.resulta
      elsif ku.operatorkode='MUL' then resultat.resultattall := resultat1.resultattall * resultat2.resulta          elsif ku.operatorkode='MUL' then resultat.resultattall := resultat1.resultattall * resultat2.resulta
      elsif ku.operatorkode='DVD' then resultat.resultattall := divider(resultat1.resultattall, resultat2.          elsif ku.operatorkode='DVD' then resultat.resultattall := divider(resultat1.resultattall, resultat2.
      elsif ku.operatorkode='EQ'  then boo := resultat1.resultattall = resultat2.resultattall;                      elsif ku.operatorkode='EQ'  then boo := resultat1.resultattall = resultat2.resultattall;
      elsif ku.operatorkode='NE'  then boo := resultat1.resultattall <> resultat2.resultattall;                     elsif ku.operatorkode='NE'  then boo := resultat1.resultattall <> resultat2.resultattall;
      elsif ku.operatorkode='GT'  then boo := resultat1.resultattall > resultat2.resultattall;                      elsif ku.operatorkode='GT'  then boo := resultat1.resultattall > resultat2.resultattall;
      elsif ku.operatorkode='GE'  then boo := resultat1.resultattall >= resultat2.resultattall;                     elsif ku.operatorkode='GE'  then boo := resultat1.resultattall >= resultat2.resultattall;
      elsif ku.operatorkode='LT'  then boo := resultat1.resultattall < resultat2.resultattall;                      elsif ku.operatorkode='LT'  then boo := resultat1.resultattall < resultat2.resultattall;
      elsif ku.operatorkode='LE'  then boo := resultat1.resultattall <= resultat2.resultattall;                     elsif ku.operatorkode='LE'  then boo := resultat1.resultattall <= resultat2.resultattall;
      end if;                                                                                                       end if;

      if ku.operatorkode in ('EQ','NE','GT','GE','LT','LE') then                                                    if ku.operatorkode in ('EQ','NE','GT','GE','LT','LE') then
        resultat.resultattypekode := 'B';                                                                             resultat.resultattypekode := 'B';
        resultat.resultattall := null;                                                                                resultat.resultattall := null;
        if boo then resultat.resultatkode := 'SANN';                                                                  if boo then resultat.resultatkode := 'SANN';
        else        resultat.resultatkode := 'USANN'; ikke_oppbrukt(nr1 + 1); end if;                                 else        resultat.resultatkode := 'USANN'; ikke_oppbrukt(nr1 + 1); end if;
      end if;                                                                                                       end if;

      if resultat.resultatkode = 'SANN' or ku.operatorkode not in ('EQ','NE','GT','GE','LT','LE') then              if resultat.resultatkode = 'SANN' or ku.operatorkode not in ('EQ','NE','GT','GE','LT','LE') then
        resultat.antall_fag         := resultat1.antall_fag      + resultat2.antall_fag;                              resultat.antall_fag         := resultat1.antall_fag      + resultat2.antall_fag;
        resultat.omfang             := resultat1.omfang          + resultat2.omfang;                                  resultat.omfang             := resultat1.omfang          + resultat2.omfang;
        resultat.vekt               := resultat1.vekt            + resultat2.vekt;                                    resultat.vekt               := resultat1.vekt            + resultat2.vekt;
        resultat.antall_tallkar     := resultat1.antall_tallkar  + resultat2.antall_tallkar;                          resultat.antall_tallkar     := resultat1.antall_tallkar  + resultat2.antall_tallkar;
        resultat.sum_tallkar        := resultat1.sum_tallkar     + resultat2.sum_tallkar;                             resultat.sum_tallkar        := resultat1.sum_tallkar     + resultat2.sum_tallkar;
        resultat.snitt_tallkar      := divider(resultat.sum_tallkar, resultat.antall_tallkar);                        resultat.snitt_tallkar      := divider(resultat.sum_tallkar, resultat.antall_tallkar);
        resultat.fordypninger_foert := resultat1.fordypninger_foert + resultat2.fordypninger_foert;                   resultat.fordypninger_foert := resultat1.fordypninger_foert + resultat2.fordypninger_foert;
      end if;                                                                                                       end if;

                                                                                                           >      elsif
                                                                                                           >        resultat1.resultattypekode = 'T' and
                                                                                                           >        resultat2.resultattypekode = 'B' and resultat2.resultatkode = 'USANN'
                                                                                                           >        or
                                                                                                           >        resultat1.resultattypekode = 'B' and resultat1.resultatkode = 'USANN' and
                                                                                                           >        resultat2.resultattypekode = 'T'
                                                                                                           >      then
                                                                                                           >        resultat.resultattypekode := 'B';
                                                                                                           >        resultat.resultatkode := 'USANN';
                                                                                                           >        resultat.resultattall := null;
                                                                                                           >        ikke_oppbrukt(nr1 + 1);

    else                                                                                                          else
      error('Mix av B(oolean)- og T(all)-operander, kunr='||p_kravuttrykknr||                                       error('Mix av B(oolean)- og T(all)-operander, kunr='||p_kravuttrykknr||
                                                 ', res1='||resultat1.resultattypekode||                                                                       ', res1='||resultat1.resultattypekode||
                                                 ', res2='||resultat2.resultattypekode);                                                                       ', res2='||resultat2.resultattypekode);
    end if;                                                                                                       end if;

    if resultat.antall_fag > 0 then denne := resultat; end if;                                                    if resultat.antall_fag > 0 then denne := resultat; end if;
    logg_melding(p_kravversjonkode, p_kravuttrykknr, resultat, nr1+1, kravuttrykknr_forrige);                     logg_melding(p_kravversjonkode, p_kravuttrykknr, resultat, nr1+1, kravuttrykknr_forrige);

    loggnivaa_current := loggnivaa_forrige;                                                                       loggnivaa_current := loggnivaa_forrige;
    kravuttrykknr_current := kravuttrykknr_forrige;                                                               kravuttrykknr_current := kravuttrykknr_forrige;
    return resultat;                                                                                              return resultat;

  end kontroller_uttrykk;                                                                                       end kontroller_uttrykk;

  procedure kontroller (                                                                                        procedure kontroller (
    p_vmnr             in  kontrollresultat.vmnr%type,                                                     |      p_vmnr             in  v_kontrollresultat.vmnr%type,
    p_kravkode         in  kontrollresultat.kravkode%type,                                                 |      p_kravkode         in  v_kontrollresultat.kravkode%type,
    p_loggnivaa        in  number default 4,                                                                      p_loggnivaa        in  number default 4,
    p_kravversjonkode  in  kontrollresultat.kravversjonkode%type default null                              |      p_kravversjonkode  in  v_kontrollresultat.kravversjonkode%type default null
  ) is                                                                                                          ) is
    kversjonkode           kravuttrykk.kravversjonkode%type := p_kravversjonkode;                          |      kversjonkode           v_kravuttrykk.kravversjonkode%type := p_kravversjonkode;
    kravuttrykknr_start    kravuttrykk.kravuttrykknr%type  := null;                                        |      kravuttrykknr_start    v_kravuttrykk.kravuttrykknr%type  := null;
    resultat               resultattype;                                                                          resultat               resultattype;
    naa                    date := sysdate;                                                                       naa                    date := sysdate;
                                                                                                           >      hode                   varchar2(600);
  begin                                                                                                         begin

    -- Einars kludring, sett c_vmnr for logging                                                            |      -- Brukes i procedure logg
    c_vmnr                := p_vmnr;                                                                              c_vmnr                := p_vmnr;
                                                                                                           >      linjenr_logg          := 0;

    loggnivaa_current := p_loggnivaa;                                                                             loggnivaa_current := p_loggnivaa;

    -- Initierer og tømmer tabell oppbrukte_fag fra forrige kontroll                                       |      -- Initierer og tømmer tabell v_oppbrukte_fag fra forrige kontroll
    oppbrukte_fag_siste_nr := null;                                                                               oppbrukte_fag_siste_nr := null;
    delete from oppbrukte_fag;                                                                             |      delete from v_oppbrukte_fag;

    -- Kversjonkode settes til nyeste versjon som har gitt kravkode dersom kravversjon                            -- Kversjonkode settes til nyeste versjon som har gitt kravkode dersom kravversjon
    -- ikke er angitt som parameter                                                                               -- ikke er angitt som parameter
    if kversjonkode is null then                                                                                  if kversjonkode is null then
      select kravversjonkode                                                                                        select kravversjonkode
      into kversjonkode                                                                                             into kversjonkode
      from kravversjon                                                                                              from kravversjon
      where kravversjondato=                                                                                        where kravversjondato=
        (select max(kv.kravversjondato) from kravversjon kv, krav k                                                   (select max(kv.kravversjondato) from kravversjon kv, krav k
         where kv.kravversjonkode=k.kravversjonkode                                                                    where kv.kravversjonkode=k.kravversjonkode
         and k.kravkode=p_kravkode);                                                                                   and k.kravkode=p_kravkode);
    end if;                                                                                                       end if;

    -- Husker hvilke kravuttrykknr som har koblet en eller flere kravmeldinger                                    -- Husker hvilke kravuttrykknr som har koblet en eller flere kravmeldinger
    -- til seg. Dette for å gjøre procedure logg_melding mye raskere, siden den                                     -- til seg. Dette for å gjøre procedure logg_melding mye raskere, siden den
    -- kalles så ofte.                                                                                             -- kalles så ofte.
    -- Husker også eksplisitt satt loggnivå ved de kravuttrykknr det gjelder.                                       -- Husker også eksplisitt satt loggnivå ved de kravuttrykknr det gjelder.
    har_melding := tom_boolean_tabell; -- eneste måte å slette hashtabell på                                         har_melding := tom_boolean_tabell; -- eneste måte å slette hashtabell på
    loggnivaa   := tom_integer_tabell;                                                                            loggnivaa   := tom_integer_tabell;
    for m in (select * from kravmelding where kravversjonkode = kversjonkode)                                     for m in (select * from kravmelding where kravversjonkode = kversjonkode)
    loop                                                                                                          loop
      if m.kravmeldingtypekode = 'LOGG' then                                                                        if m.kravmeldingtypekode = 'LOGG' then
        loggnivaa(m.kravuttrykknr) := to_number(m.meldingtekst);                                                      loggnivaa(m.kravuttrykknr) := to_number(m.meldingtekst);
      else                                                                                                          else
        har_melding(m.kravuttrykknr) := true;                                                                         har_melding(m.kravuttrykknr) := true;
      end if;                                                                                                       end if;
    end loop;                                                                                                     end loop;

    -- Husker hvilken kravkode som er koblet til et kravuttrykknr                                                 -- Husker hvilken kravkode som er koblet til et kravuttrykknr
    -- og finner startnr'et.                                                                                      -- og finner startnr'et.
    kravkode := tom_string_tabell;                                                                                kravkode := tom_string_tabell;
    for k in ( select kravkode, kravuttrykknr from krav where kravversjonkode = kversjonkode )                    for k in ( select kravkode, kravuttrykknr from krav where kravversjonkode = kversjonkode )
    loop                                                                                                          loop
      kravkode(k.kravuttrykknr) := k.kravkode;                                                                      kravkode(k.kravuttrykknr) := k.kravkode;
      if k.kravkode = p_kravkode then                                                                               if k.kravkode = p_kravkode then
        kravuttrykknr_start := k.kravuttrykknr;                                                                       kravuttrykknr_start := k.kravuttrykknr;
      end if;                                                                                                       end if;
    end loop;                                                                                                     end loop;

   -- Parseren har lagt inn flere kravuttrykk med "operator" av type OPT for fagliste                            -- Parseren har lagt inn flere kravuttrykk med "operator" av type OPT for fagliste
   -- på et kravuttrykknr der man kan hoppe over kravuttrykknr'et dersom ingen                                    -- på et kravuttrykknr der man kan hoppe over kravuttrykknr'et dersom ingen
   -- av fagene finnes på vitnemålet (...mer...)                                                                   -- av fagene finnes på vitnemålet (...mer...)
   skip_kravuttrykk := tom_boolean_tabell;                                                                       skip_kravuttrykk := tom_boolean_tabell;

   for ku in (                                                                                                   for ku in (
     select distinct kravuttrykknr1 from kravuttrykk                                                               select distinct kravuttrykknr1 from kravuttrykk
     where kravversjonkode=kversjonkode                                                                            where kravversjonkode=kversjonkode
     and operatorkode='OPT'                                                                                        and operatorkode='OPT'
     and kravuttrykknr1 not in                                                                                     and kravuttrykknr1 not in
       (select distinct kravuttrykknr1 from kravuttrykk                                                              (select distinct kravuttrykknr1 from kravuttrykk
        where kravversjonkode=kversjonkode                                                                            where kravversjonkode=kversjonkode
        and operatorkode='OPT'                                                                                        and operatorkode='OPT'
        and fagkode1 in (select fagkode from vitnemaalfag                                                  |          and fagkode1 in (select fagkode from v_vitnemaalfag
                         where vmnr=p_vmnr                                                                                             where vmnr=p_vmnr
                         ))                                                                                                            ))
   )                                                                                                             )
   loop                                                                                                          loop
     skip_kravuttrykk(ku.kravuttrykknr1) := true;                                                                  skip_kravuttrykk(ku.kravuttrykknr1) := true;
     --logg('Skipper '||ku.kravuttrykknr1, 4);                                                                     --logg('Skipper '||ku.kravuttrykknr1, 4);
   end loop;                                                                                                     end loop;

    -- Trenger disse                                                                                              -- Trenger disse
    resultat_SANN.resultattypekode        := 'B';                                                                 resultat_SANN.resultattypekode        := 'B';
    resultat_SANN.resultatkode            := 'SANN';                                                              resultat_SANN.resultatkode            := 'SANN';
    resultat_SANN.resultattall            := null;                                                                resultat_SANN.resultattall            := null;
    resultat_SANN.antall_fag              := 0;                                                                   resultat_SANN.antall_fag              := 0;
    resultat_SANN.omfang                  := 0;                                                                   resultat_SANN.omfang                  := 0;
    resultat_SANN.vekt                    := 0;                                                                   resultat_SANN.vekt                    := 0;
    resultat_SANN.antall_tallkar          := 0;                                                                   resultat_SANN.antall_tallkar          := 0;
    resultat_SANN.sum_tallkar             := 0;                                                                   resultat_SANN.sum_tallkar             := 0;
    resultat_SANN.snitt_tallkar           := 0;                                                                   resultat_SANN.snitt_tallkar           := 0;
    resultat_SANN.fordypninger_foert      := 0;                                                                   resultat_SANN.fordypninger_foert      := 0;
    resultat_USANN := resultat_SANN;                                                                              resultat_USANN := resultat_SANN;
    resultat_USANN.resultatkode           := 'USANN';                                                             resultat_USANN.resultatkode           := 'USANN';

    -- Nullstiller                                                                                                -- Nullstiller
    denne := resultat_USANN;                                                                                      denne := resultat_USANN;

    -- Sletter eventuellt tidligere kontrollresultat av kontroll på samme vitnemaal med samme                      -- Sletter eventuellt tidligere kontrollresultat av kontroll på samme vitnemaal med samme
    -- kravkode på samme tidspunkt (sekund), og oppretter plass for nytt kontrollresultat                          -- kravkode på samme tidspunkt (sekund), og oppretter plass for nytt kontrollresultat
    delete from kontrollresultat                                                                           |      delete from v_kontrollresultat
    where vmnr=p_vmnr                                                                                             where vmnr=p_vmnr
    and kravversjonkode=kversjonkode                                                                              and kravversjonkode=kversjonkode
    and kravkode=p_kravkode                                                                                       and kravkode=p_kravkode
    and tidspunkt=naa;                                                                                            and tidspunkt=naa;

    insert into kontrollresultat                                                                           |      insert into v_kontrollresultat
    (foedtdato,personnummer,vmnr,kravversjonkode,kravkode,tidspunkt,resultattypekode)                      |      (vmnr,kravversjonkode,kravkode,tidspunkt,resultattypekode)
    values ('24-DES-98',99999,p_vmnr,kversjonkode,p_kravkode,naa,'E');                                     |      values (p_vmnr,kversjonkode,p_kravkode,naa,'E');
                                                                                                           >
                                                                                                           >
                                                                                                           >      -- Sletter eventuell tidligere logging som måtte ligge inne for dette vitnemålet.
                                                                                                           >      -- Loggen i tabell v_nvb_logg har bare plass til en kjøringslogg pr vitnemål.
                                                                                                           >      -- Og logger overskrift (eller vitnemålskille) i toppen av logg for hvert vitnemål.
                                                                                                           >      delete from v_nvb_logg where vmnr=p_vmnr;
                                                                                                           >
                                                                                                           >      select
                                                                                                           >        '=================================================='||
                                                                                                           >        ' Vitnemål '||vmnr||'/'||to_char(foedtdato,'DDMMYY')||personnummer||'/'||elevnavn||' '||
                                                                                                           >        '=================================================='
                                                                                                           >        into hode
                                                                                                           >      from v_vitnemaal
                                                                                                           >      where vmnr=p_vmnr;
                                                                                                           >      logg('',2);
                                                                                                           >      logg('',2);
                                                                                                           >      logg('',2);
                                                                                                           >      logg('',2);
                                                                                                           >      logg(substr(hode,trunc(length(hode)/2)-38,76),2);

    -- Utfører kontrollen                                                                                          -- Utfører kontrollen

    resultat := kontroller_uttrykk(p_vmnr, kversjonkode, kravuttrykknr_start);                                    resultat := kontroller_uttrykk(p_vmnr, kversjonkode, kravuttrykknr_start);

    -- Legger resultatet på plass i tabell kontrollresultat                                                        -- Legger resultatet på plass i tabell kontrollresultat
    update kontrollresultat set                                                                            |      update v_kontrollresultat set
      resultattypekode   = resultat.resultattypekode,                                                               resultattypekode   = resultat.resultattypekode,
      resultatkode       = resultat.resultatkode,                                                                   resultatkode       = resultat.resultatkode,
      resultattall       = resultat.resultattall,                                                                   resultattall       = resultat.resultattall,
      antall_fag         = resultat.antall_fag,                                                                     antall_fag         = resultat.antall_fag,
      omfang             = resultat.omfang,                                                                         omfang             = resultat.omfang,
      vekt               = resultat.vekt,                                                                           vekt               = resultat.vekt,
      antall_tallkar     = resultat.antall_tallkar,                                                                 antall_tallkar     = resultat.antall_tallkar,
      sum_tallkar        = resultat.sum_tallkar,                                                                    sum_tallkar        = resultat.sum_tallkar,
      snitt_tallkar      = resultat.snitt_tallkar,                                                                  snitt_tallkar      = resultat.snitt_tallkar,
      fordypninger_foert = resultat.fordypninger_foert                                                              fordypninger_foert = resultat.fordypninger_foert
    where                                                                                                         where
      vmnr=p_vmnr and                                                                                               vmnr=p_vmnr and
      kravversjonkode=kversjonkode and                                                                              kravversjonkode=kversjonkode and
      kravkode=p_kravkode and                                                                                       kravkode=p_kravkode and
      tidspunkt=naa;                                                                                                tidspunkt=naa;

    -- Logger sluttrapport                                                                                        -- Logger sluttrapport
    logg_sluttrapport(p_vmnr, resultat, kversjonkode, p_kravkode, 5);                                             logg_sluttrapport(p_vmnr, resultat, kversjonkode, p_kravkode, 5);

    commit;                                                                                                |          --    commit;

  end kontroller;                                                                                               end kontroller;

  -- bruker for testing/tidtaking                                                                               -- bruker for testing/tidtaking
  procedure kontroller10 (                                                                                      procedure kontroller10 (
    p_vmnr             in  kontrollresultat.vmnr%type,                                                     |      p_vmnr             in  v_kontrollresultat.vmnr%type,
    p_kravkode         in  kontrollresultat.kravkode%type,                                                 |      p_kravkode         in  v_kontrollresultat.kravkode%type,
    p_loggnivaa        in  number default 4,                                                                      p_loggnivaa        in  number default 4,
    p_kravversjonkode  in  kontrollresultat.kravversjonkode%type default null                              |      p_kravversjonkode  in  v_kontrollresultat.kravversjonkode%type default null
  ) is                                                                                                          ) is
  begin                                                                                                         begin
    for i in 1 .. 11                                                                                              for i in 1 .. 11
    loop                                                                                                          loop
      kontroller(                                                                                                   kontroller(
        p_vmnr,                                                                                                       p_vmnr,
        p_kravkode,                                                                                                   p_kravkode,
        p_loggnivaa,                                                                                                  p_loggnivaa,
        p_kravversjonkode);                                                                                           p_kravversjonkode);
    end loop;                                                                                                     end loop;
  end;                                                                                                          end;

  procedure kontroller_alle_vitnemaal(                                                                          procedure kontroller_alle_vitnemaal(
    p_kravkode         in  kontrollresultat.kravkode%type,                                                 |      p_kravkode         in  v_kontrollresultat.kravkode%type,
    p_loggnivaa        in  number default 1,                                                                      p_loggnivaa        in  number default 1,
    p_kravversjonkode  in  kontrollresultat.kravversjonkode%type default null                              |      p_kravversjonkode  in  v_kontrollresultat.kravversjonkode%type default null
  ) is                                                                                                          ) is
  begin                                                                                                         begin
    for vm in (select vmnr from vitnemaal )                                                                |      for vm in (select vmnr from v_vitnemaal )
    loop                                                                                                          loop
      kontroller(                                                                                                   kontroller(
        vm.vmnr,                                                                                                      vm.vmnr,
        p_kravkode,                                                                                                   p_kravkode,
        p_loggnivaa,                                                                                                  p_loggnivaa,
        p_kravversjonkode                                                                                             p_kravversjonkode
      );                                                                                                            );
    end loop;                                                                                                     end loop;
  end;                                                                                                          end;

end nvb;                                                                                                      end nvb;
/                                                                                                             /

-- Vis eventuelle kompileringsfeilmeldinger                                                                |  -- Vis eventuelle kompileringsfeil
sho err                                                                                                       sho err

                                                                                                           <
                                                                                                           <
-- HJELPETABELLER ------------------------------------------------------------------                       <
                                                                                                           <
-- drop table oppbrukte_fag;                                                                               <
-- create table oppbrukte_fag (                                                                            <
--   fagkode varchar2(6) not null primary key,                                                             <
--   nr      number(4)   not null                                                                          <
-- );                                                                                                      <
-- create index i_oppbrukte_fag on oppbrukte_fag(nr);                                                      <
--                                                                                                         <
-- drop table nvb_logg;                                                                                    <
-- create table nvb_logg (                                                                                 <
--   txt varchar2(2000)                                                                                    <
-- );                                                                                                      <