home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / BASIC / QBDBAS / QBDBASE.DOC < prev    next >
Text File  |  1991-10-18  |  12KB  |  281 lines

  1.  DEMONSTRATIE PROGRAMMA QBDBASE.BAS versie 1.1
  2.  
  3.  LEES en bewerk dBaseIII en dBaseIV BESTANDEN met QuickBasic 4.5
  4.  
  5.  -----------------------------------------------------------------------
  6.  Start QuickBasic met: QB QBDBASE /AH /G /LQB.QLB
  7.                                   ===============
  8.  -----------------------------------------------------------------------
  9.  
  10.  Doel:    Het lezen van dBase III en IV data- en memofiles.
  11.  
  12.  Werking: Dit voorbeeld programma toont eerst de header structuur
  13.           en daarna de records van een dBase file op het scherm.
  14.       
  15.           Als in de lay-out van een record ook een "memo" veld is
  16.           opgenomen, dan wordt ook de inhoud van het memo getoond.
  17.           De memo velden zijn opgeslagen in een bestand met dezelfde naam
  18.           als het database bestand, echter met de extensie .DBT
  19.       
  20.           Deze routines kunnen worden gebruikt om de records van een dBase
  21.           bestand in uw eigen database programma binnen te halen en verder 
  22.           te bewerken.
  23.       
  24.      ->   Het rechtstreeks wijzigen van een dBase bestand is natuurlijk
  25.      ->   ook mogelijk; pas echter op met het veranderen van de sleutel-
  26.      ->   velden van een dBase bestand. Eventueel reeds aanwezige indexen
  27.      ->   kunnen daardoor corrupt worden.
  28.  
  29.  De structuur van een dBase bestand.
  30.  --------------------------------------
  31.  
  32.  Het databestand.
  33.  ----------------
  34.  Het eerste gedeelte van een dBase bestand wordt de "header" genoemd.
  35.  Dit gedeelte bevat onder andere informatie over het dBase versie nummer,
  36.  de lengte van het headergedeelte en beschrijvingen van de velden. Het is
  37.  verdeeld in blokken van 32 bytes.
  38.  
  39.  
  40.  HEADER LAY-OUT.
  41.  ---------------
  42.  
  43.  Het eerste blok van 32 bytes bevat de volgende informatie:
  44.  
  45.    Versienummer             -  1 byte
  46.    Laatste datum bijgewerkt -  3 bytes (jaaar/maand/dag)
  47.    Aantal records           -  4 bytes (LONG INTEGER)
  48.    Lengte van de header     -  2 bytes (INTEGER)
  49.    RecordLengte             -  2 bytes (INTEGER)
  50.    Rest                     - 20 bytes
  51.                              ---------
  52.                      TOTAAL : 32 bytes
  53.  
  54.  Versienummer.
  55.  -------------
  56.  De eerste byte geeft aan met welke versie van dBase het bestand is
  57.  aangemaakt en of er wel of geen memovelden aanwezig zijn.
  58.  
  59.  Hex  Decimaal  Betekenins.
  60.  ---  --------  -------------------------------------------
  61.  &H3      3     dBase III bestand zonder memo velden.
  62.  &H83   131     dBase III bestand met memovelden.
  63.  &H63    99     dBase IV  bestand zonder memovelden.
  64.  &H8B   139     dBase IV  bestand met memo velden.
  65.  
  66.  N.B. Als deze byte aangeeft dat er memovelden zijn, dan dient er ook
  67.       een .DBT bestand aanwezig te zijn, waarin die memo's zijn opgeslagen.
  68.       Neem echter niet zo maar aan, dat dit .DBT bestand aanwezig is,
  69.       voer eerst een kontrole uit met de funktie "BestandAanwezig".
  70.  
  71.  Laatste datum bijgewerkt.
  72.  -------------------------
  73.  De datum waarop de database het laatste is bijgewerkt staat in 3 bytes.
  74.  De Ascii waarden staan in de volgorde jaar/maand/dag.
  75.  
  76.  Aantal records.
  77.  ---------------
  78.  Het totale aantal records is opgeslagen als LONG INTEGER.
  79.  
  80.  Lengte van de header.
  81.  ---------------------
  82.  Omdat een database meer of minder velden kan bevatten, is de lengte van
  83.  de header variabel. Deze lengte is opgeslagen als INTEGER.
  84.  
  85.  RecordLengte.
  86.  -------------
  87.  Alle records in een dBase bestand hebben een vaste lengte. De waarde
  88.  hiervan staat in de header als INTEGER.
  89.  
  90.  Rest.
  91.  -----
  92.  De "rest" van 20 bytes wordt in dit programma niet gebruikt.
  93.  
  94.  Dit eerste blok van 32 bytes wordt in het programma gedefineerd in een
  95.  TYPE record variabele met de naam dbHeader.
  96.  
  97.  
  98.  RECORD LAYOUT.
  99.  --------------
  100.  Elk volgende blok van 32 bytes bevat de veldbeschrijving van een record.
  101.  
  102.    Veldnaam                 - 11 bytes
  103.    VeldType                 -  1 byte
  104.    DataAdres                -  4 bytes
  105.    VeldLengte               -  1 byte
  106.    Aantal decimalen         -  1 byte
  107.    Rest                     - 14 bytes
  108.                               --------
  109.                      TOTAAL   32 bytes
  110.  
  111.  Veldnaam.
  112.  ---------
  113.  De naam die de gebruiker aan een veld heeft gegeven. De naam wordt
  114.  afgesloten met CHR$(0). Een veldnaam mag alleen letters, cijfers of "_"
  115.  bevatten.
  116.  
  117.  Veldtype.
  118.  ---------
  119.  Deze byte kan de volgende inhoud hebben:
  120.    C - Character - alfa/numeriek - veld bevat uitsluitned tekst.
  121.    N - Numeric   - numeriek      - veld bevat een getal
  122.    D - Date      - datum         - veld bevat een datum JJJJMMDD
  123.    L - Logical   - logisch veld  - veld bevat T/F of Y/N; waar of niet waar.
  124.    M - Memo      - aantekeningen - Memo aanwezig in *.DBT bestand.
  125.  
  126.  Data adres.
  127.  -----------
  128.  Dit veld bevat de veld offset in memory. Het veld wordt in dit
  129.  programma niet gebruikt.
  130.  
  131.  Veld lengte.
  132.  ------------
  133.  De Ascii waarde is de lengte van het veld. Voor een Numeriek veld is
  134.  het de lengte, inclusief de decimale punt.
  135.  
  136.  Aantal decimalen.
  137.  -----------------
  138.  De Ascii waarde is het aantal decimalen van een decimaal veld.
  139.  
  140.  Rest.
  141.  -----
  142.  De "rest" van 14 bytes wordt in dit programma niet gebruikt.
  143.  
  144.  
  145.  AANTAL VELDEN.
  146.  --------------
  147.  Het aantal gedefinieerde velden is gelijk aan de lengte van de header
  148.  gedeeld door 32. De uitkomst moet met 1 worden verminderd, omdat het
  149.  eerste blok van 32 bytes de header omschrijving bevat.
  150.  
  151.    AantalVelden% = (Header.HeaderLengte \ 32) - 1
  152.  
  153.  
  154.  WERKELIJKE RECORDLENGTE.
  155.  ------------------------
  156.  Als dit programma wordt gestart, dan verschijnt eerst een overzicht
  157.  met de gegevens uit de header en vervolgens de veld beschrijvingen.
  158.  Als u de lengten van elk veld bij elkaar optelt, dat zult u merken, dat
  159.  de som van de veldlengten steeds 1 byte minder is dan de recordlengte
  160.  die in de header informatie staat.
  161.  
  162.  Die extra byte wordt steeds vooraan in elk record geplaatst en geeft aan
  163.  of een record geldig is of niet. Als de gebruiker een record heeft gedelete,
  164.  dan wordt in dat veld een "*" teken geplaatst.
  165.  
  166.  DE RECORDS.
  167.  -----------
  168.  Na het header gedeelte met algemene- en veldinformatie worden de records
  169.  geplaatst. Daarbij is de volgende informatie van belang.
  170.  
  171.    STATUS VELD   - De eerste positie van elk record geeft de status van het
  172.                    record weer. Indien het veld gevuld is met een "*" dan
  173.                    is het record ongeldig gemaakt.
  174.  
  175.    TEKST VELD    - Een tekst wordt aangevuld met spaties tot het einde
  176.                    van het veld.
  177.  
  178.    NUMERIEK VELD - Een numeriek veld is een getal of een bedrag. In het
  179.                    record wordt het precies zo weggeschreven als het
  180.                    op het scherm wordt ingevoerd. Let op de deciamle punt.
  181.                    Uit de header informatie kan worden afgeleid met hoeveel
  182.                    decimalen moet worden gewerkt. Vertaal een veld met
  183.                  
  184.                       N! = VAL(Veld$) of met N# = VAL(Veld$)
  185.                  
  186.                    naar een singel of double precision numerieke variabele.
  187.  
  188.                    Als het aantal decimalen nul is, dan kan - afhankelijk
  189.                    van de lengte van het veld - een omzetting naar een
  190.                    integer of long integer plaatsvinden met :
  191.  
  192.                       N% = VAL(Veld$) of met N& = VAL(Veld$)
  193.  
  194.    DATUM VELD    - Een datum veld is altijd 8 bytes lang. De datum wordt
  195.                    op disk opgeslagen in het formaat JJJJMMDD. Dus 31 december
  196.                    1991 wordt als 19911231 in het record geplaatst.
  197.  
  198.    LOGISCH VELD  - Dit veld kan "Y" of "T" bevatten. in beide gevallen
  199.                    is de betekenis "Ja", "Waar" of True. Het is een Boolean
  200.                    waarde. Als er iets anders dan "T" of "Y" is vermeld,
  201.                    dan is de betekenis "Nee", "Niet waar" cq "False".
  202.  
  203.                    Als u een INTEGER de waarde -1 = True of 0 = False wilt
  204.                    geven, doe dat dan als volgt:
  205.  
  206.                    IF INSTR("YT",LogischVeld$) > 0 THEN
  207.                      Betaald% = -1
  208.                    ELSE
  209.                      Betaald% = 0
  210.                    END IF
  211.  
  212.    MEMO VELD     - In het record zelf is de veldlengte van een memo altijd 
  213.                    10 bytes. Als er bij een record ook daadwerkelijk 
  214.                    aantekeningen in een memo zijn gemaakt, dan bevat dat veld 
  215.                    een getal. Ook dit getal staat in een STRING formaat en kan 
  216.                    met de funktie Pointer& = VAL(Veld$) naar een LONG INTEGER 
  217.                    variabele worden overgezet. Dit getal wijst naar een blok 
  218.                    tekst in een .DBT bestand, dat door dBase zelf wordt aangemaakt.
  219.  
  220.  MEMO BESTAND
  221.  ------------
  222.  Als in de structuur van een record een Memo veld is gedefinieerd, dan wordt
  223.  de eerste keer, dat er daadwerkelijk een aantekening gemaakt wordt, een
  224.  nieuw bestand aangemaakt. Dat bestand krijgt dezelfde naam als het data-
  225.  base bestand, echter met de extensie .DBT.
  226.  
  227.  In dat bestand worden de aantekeningen geplaatst IN BLOKKEN VAN 512 BYTES.
  228.  
  229.  De memo-pointer in het database record wijst naar het blok waarin een stuk
  230.  memotekst start. Daarbij wordt het eerste blok van 512 bytes door dBase
  231.  zelf gebruikt. Als een memo-pointer de waarde "1" bevat dan start de memo-
  232.  tekst op de 513e byte - dus het 2e blok - in het .DBT bestand. De memo-
  233.  pointer moet dus met 1 worden verhoogd om het juiste blok te berekenen.
  234.  De formule is dan ook : Startbyte = (MemoPointer * 512) + 1.
  235.  
  236.  dBase III plaatst vanaf StartByte de memo tekst. Het einde van de tekst
  237.  wordt aangegeven met &H1A &H1A. De tekst kan dus eenvoudig in blokken
  238.  van 512 bytes worden binnen gehaald, waarbij er steeds op getest moet worden
  239.  of die twee "einde tekst" bytes 1A 1A in de string voorkomen.
  240.  
  241.  Een memo-tekst in dBase III is maximaal 4000 bytes lang. Dat is tevens het
  242.  maximale aantal bytes dat met de dBase III tekstverwerker MODIFY COMMAND
  243.  kan worden bewerkt.
  244.  
  245.  dBase IV behandelt de memo-teksten in het .DBT bestand op een andere manier.
  246.  De eerste 8 bytes van het startblok zijn gereserveerd. De bytes 1 t/m 4
  247.  bevatten FF FF 00 08 hex. De volgende 4 bytes bevatten de lengte van de
  248.  memotekst als LONG INTEGER. De memotekst zelf start op de 9e byte.
  249.  
  250.  Als uw programma heeft geconstateerd, dat er sprake is van een dBase IV
  251.  bestand, dan moet na het inlezen van het eerste blok tekst van 512 bytes
  252.  dus gekontroleerd worden of de eerste twee bytes FF FF hex bevatten.
  253.  Is dat het geval, dan moeten byte 5 t/m 8 omgezet worden naar een LONG
  254.  INTEGER waarde, die de tekstlengte aangeeft. De tekst begint dan vanaf
  255.  byte 9.
  256.  
  257.  Maar helaas... daarmee zijn we er nog niet. dBase IV bewerkt zonder
  258.  problemen database bestanden, die met dBase III zijn aangemaakt. En ook
  259.  de bijbehorende .DBT memobestanden worden probleemloos behandeld. Maar
  260.  het kan zijn, dat een .DBT memobestand, dat onder dBase III is aangemaakt
  261.  nog niet door dBase IV is behandeld. Dan kan het voorkomen, dat het data-
  262.  base bestand wel al naar dBase IV formaat is omgezet, maar het erbij horende
  263.  .DBT memobestand nog het oude dBase III formaat heeft.
  264.  
  265.  Om het nog erger te maken: Als met dBase IV een memobestand wordt bewerkt
  266.  dat onder dBase III is aangemaakt, dan zal dBase IV elk gewijzigde memo
  267.  in het nieuwe formaat met FFh FFh aan het begin ervan wegschrijven. Zo
  268.  kan het dus gebeuren, dat in een en hetzelfde .DBT bestand memo's voor-
  269.  komen met zowel het oude als het nieuwe formaat!
  270.  
  271.  Dit probleem is simpel op te lossen. Tijdens het inlezen van het eerste
  272.  blok memotekst moet worden gekontroleerd of de eerste twee posities de
  273.  tekens FF FF hex bevatten. Is dat het geval, dan heeft ook de memo het
  274.  dBase IV formaat en de tekstlengte staat in byte 5 t/m 9. Zo niet, dan 
  275.  heeft de memo nog het oude formaat en start op byte 1. Er moet dan 
  276.  worden gezocht naar de opeenvolgende tekens 1A 1A hex om de lengte van 
  277.  de mometekst te kunnen bepalen.
  278.  
  279.                             -o-o-o-o-o-
  280.  
  281.