Announcement

Collapse
No announcement yet.

BTRCALL versus BTRV

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #21
    Was the old file saved using MBF format?
    If so, I think that would be a problem with anything saved as SINGLE.
    Does your type array only have 1 UDT element which is the length of the entire UDT?
    You are reading and writing the UDT values (and not looking at the KeyValue$), right$.
    The KeyValue$ would not be used after reading.
    The first 10 bytes of the UDT would not be the key unless the first 10 bytes of the file is the key (which I'll guess it is.)
    Last edited by Mike Doty; 20 Dec 2008, 04:28 PM.
    CMD shortcut to open any location:
    %windir%\system32\cmd.exe /k " cd\ & x: & cd x:\xxxx
    Change to run as administrator
    How long is an idea? Write it down.

    Comment


    • #22
      Well I tried about every combination of stuff, with, without the DOS open, is seems to work the same. I just have garbage in the data buffer. Not sure what to do next.

      Comment


      • #23
        Are both files in Btrieve 6 format?
        Post some code.
        CMD shortcut to open any location:
        %windir%\system32\cmd.exe /k " cd\ & x: & cd x:\xxxx
        Change to run as administrator
        How long is an idea? Write it down.

        Comment


        • #24
          Try changing all strings to ASCIIZ. They may be moving.
          Don's code was working so definitely use his calling syntax.
          CMD shortcut to open any location:
          %windir%\system32\cmd.exe /k " cd\ & x: & cd x:\xxxx
          Change to run as administrator
          How long is an idea? Write it down.

          Comment


          • #25
            I am on Btrieve Version 7. I know i did a conversion a few years ago when we moved from Novell to Pervasive SQL.

            The way my code works is that I string my variables into the data Buffer using MID$, MKD$ MKS$, and MKI$. When I read a record, I put the characters back into variables using MID$, CVD$, CVS$, and CVI$.

            So I assume that I would not have to have more than one UDT element of the length of the databuffer?

            Let me look at a few other things. I appreciate your help. Sorry to waste your Saturday. It is snowing here in Wisconsin, so not much else to do but try to figure thisi out.

            Comment


            • #26
              Was Visual Basic ever used with a TYPE statement?
              If so, DWORD FILL might be needed if the alignment is incorrect on boundaries.
              Example only:
              Code:
              TYPE MyType DWORD FILL
                MyKey AS STRING * 10
                Something AS  INTEGER
                Dummy AS STRING * 32
              END TYPE
              Last edited by Mike Doty; 20 Dec 2008, 05:26 PM.
              CMD shortcut to open any location:
              %windir%\system32\cmd.exe /k " cd\ & x: & cd x:\xxxx
              Change to run as administrator
              How long is an idea? Write it down.

              Comment


              • #27
                The way my code works is that I string my variables into the data Buffer using MID$, MKD$ MKS$, and MKI$. When I read a record, I put the characters back into variables using MID$, CVD$, CVS$, and CVI$.
                ...
                So I assume that I would not have to have more than one UDT element of the length of the databuffer?
                That is "doable" but you would be wasting the features of the compiler.

                This technique may have been your best option back in 1983-1984 or so, but there are at least two ways it would behoove you to look at:
                • Use a User-Defined Type (UDT) with one member per data element. TYPE SET or LSET the UDT into a string variable to pass the databuffer to the BTrieve call.
                • Use the FIELD statement to break up your data bufffer string into discrete data items.



                MCM
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #28
                  Hi Mike. Thanks for your continued patience with me. You are correct, this code is early to mid 80's. The business was going to switch to SAP Small Business, but after two years of frustration with lack of function and performance, we are back to Basic (no pun intended). I am thinking about going to UDT to define the variables.

                  For the little test I have, this is the record
                  Variable Type Character Pos in Record Len
                  F10SCON String 1 10
                  F10SNOPL# DWord 11 8
                  F10NOIN# DWord 19 8
                  F10SLRNU! Integer 27 2
                  F10SPACK# DWord 29 8
                  F10SINVC# DWord 37 8

                  I assume I would put those into a TYPE statement similar to the UDT you sent me yesterday. Can you show me what the structure might look like?

                  Does this mean, I would have to convert all my current data, or should this work as is?

                  Roy

                  Comment


                  • #29
                    I'll post the UDT in a second.
                    Can you STEP and GET NEXT through your current file and read the first 10-bytes of all records?
                    If so, then it is a CV MK conversion problem and the old file should be readable as it is probably an alignment or MBF issue.
                    Last edited by Mike Doty; 21 Dec 2008, 11:55 AM.
                    CMD shortcut to open any location:
                    %windir%\system32\cmd.exe /k " cd\ & x: & cd x:\xxxx
                    Change to run as administrator
                    How long is an idea? Write it down.

                    Comment


                    • #30
                      For UDTs... If a field in your data string is written with MKI$() and read with CVI(), the member is "AS INTEGER" ; for MKS$()/CVS(), it's "AS SINGLE" , etc etc.

                      The only problem you might encounter is if your SINGLE and DOUBLE are MBF (Microsoft Binary Format). But you can just treat those as "STRING * 4" (single) and "STRING * 8" (DOUBLE) and use a conversion function. (There has to be one here somewhere).
                      Michael Mattias
                      Tal Systems (retired)
                      Port Washington WI USA
                      [email protected]
                      http://www.talsystems.com

                      Comment


                      • #31
                        Variable Type Character Pos in Record Len
                        Code:
                        'Variable Type Character Pos in Record Len
                        F10SCON String 1 10
                        F10SNOPL# DWord 11 8
                        F10NOIN# DWord 19 8
                        F10SLRNU! Integer 27 2
                        F10SPACK# DWord 29 8
                        F10SINVC# DWord 37 8
                        Well, "String 10" and "integer 2" make sense, but "dword 8" does not. For an eight-byte field, "double" would make sense, but not DWORD. Unless "DWORD" is some kind of display (character) type... but the range of a dword would require ten decimal digits, not eight.

                        Try this UDT and see what you get..
                        Code:
                        TYPE DataRecordType  BYTE
                           F10SCON  AS String * 10
                           F10SNOPL AS DOUBLE
                           F10NOIN   AS DOUBLE
                           F10SLRNU AS INTEGER
                           F10SPACK AS DOUBLE
                        END TYPE
                        MCM
                        Michael Mattias
                        Tal Systems (retired)
                        Port Washington WI USA
                        [email protected]alsystems.com
                        http://www.talsystems.com

                        Comment


                        • #32
                          Code:
                          #COMPILE EXE
                          #DIM ALL
                          TYPE MyRecordType                'Might need DWORD FILL
                            F10SCON   AS STRING * 10
                            F10SNOPL  AS DOUBLE      
                            F10NOIN   AS DOUBLE      
                            F10SLRNU  AS INTEGER    
                            F10SPACK  AS DOUBLE     
                            F10SINVC  AS DOUBLE
                          END TYPE
                          FUNCTION PBMAIN () AS LONG
                            LOCAL record AS MyRecordType
                            ? "Record length" + STR$(SIZEOF(record)) " or" + STR$(SIZEOF(MyRecordType))
                            SLEEP 2000
                          END FUNCTION
                          Last edited by Mike Doty; 21 Dec 2008, 12:09 PM. Reason: Same as MM, but added F10SINVC AS DOUBLE
                          CMD shortcut to open any location:
                          %windir%\system32\cmd.exe /k " cd\ & x: & cd x:\xxxx
                          Change to run as administrator
                          How long is an idea? Write it down.

                          Comment


                          • #33
                            Thanks, I will give this a shot. You are right. It is Double not DWord. Sorry for the confusion.

                            Comment


                            • #34
                              Well, this time I got a blank (44 character) string . However, I am not sure at this point what I am doing. I used this record for testing as it only contained on record and was small. So get next and get previous are not an option. Ihave considered working with a different file to see if I get anything that gives me a clue about what my issue is. You might be right about the Integer issue, but I think that can be worked around, if I can get the data in the buffer.

                              Here is the first part of my mainline code and the INCLUDE that handles the BTREIVE call. Maybe you can see something. I am just confused at this time.

                              Thanks. Roy

                              #COMPILER PBCC 5
                              #COMPILE EXE
                              DECLARE FUNCTION BTRCALL LIB "WBTRV32.DLL" (ByVal OpCode As Integer,_
                              POSBLOCK As Any,_
                              DataBuffer As Any,_
                              DataLength As Integer,_
                              KeyName As Any,_
                              ByVal Keylength As Integer,_
                              ByVal KeyNumber As Integer) As Integer
                              TYPE typPosBlk
                              PosBlk AS STRING*128
                              BUFFER(128) AS BYTE
                              END TYPE
                              TYPE DATABUF10
                              f1 As STRING*44
                              END TYPE
                              TYPE F10RECORD
                              F10SCNTL AS STRING*10
                              F10SNOPL AS DOUBLE
                              F10SNOIN AS DOUBLE
                              F10SLRNU AS INTEGER
                              F10SLPAC AS DOUBLE
                              F10SLINV AS DOUBLE
                              END TYPE
                              FUNCTION PBMAIN () AS LONG
                              DEFINT B,I,K
                              DIM SLVL%(9),IOPT$(9)
                              DIM F10KLEN%(2),F10TYPE$(2),F10DUP$(2),F10KEYS$(2)
                              GOTO 20000
                              100 $INCLUDE "FUNCKEYS.INC"
                              200 $INCLUDE "CONTROL.INC"
                              250 $INCLUDE "DATECHKG.INC"
                              300 $INCLUDE "DATETIME.INC"
                              350 $INCLUDE "ERRHAND.INC"
                              400 $INCLUDE "INDATA.INC"
                              700 $INCLUDE "BERROR.INC"
                              800 $INCLUDE "INITCOLR.INC"
                              900 $INCLUDE "INITBT.INC"
                              10000 $INCLUDE "F10INVC.INC"
                              20000 'Enter Program
                              PROGNAM$ = "TEST1PB"
                              COMPANY$ = SPACE$(128)
                              MID$(COMPANY$,124,5) = "TEST1"
                              MID$(COMPANY$,126,3) = "ON "
                              GOSUB 800 'Init the Colors
                              GOSUB 900 'Init Btrieve
                              GOSUB 100 'Init Function Keys
                              CONSOLE NAME " Grey Pneumatic Production System - "+MID$(COMPANY$,126,3)+" Network "+PROGNAM$
                              MAPD70$ = "#######"
                              MAPI5$ = "#####"
                              MAPD93$ = "#####.###"
                              GOSUB 10000 'Go open file #1.
                              IF B10STATUS%=0 THEN 20400 'Branch if file failed to open.
                              LOCATE 24,20: PRINT "OPEN ERROR ": PRINT B10STATUS%;: GOTO 65000
                              20400 MSG$ = " OPEN OK, Ready to Start?": IBUFF$=" ": GOSUB 200
                              20500 ON MSG% GOTO 65000,20900,20600
                              20600 BEEP: goto 20500
                              20900 b10key = "CONTROLREC": F10SCNTL$ = b10key: B10OPCODE% = -1
                              LOCATE 20,1: PRINT B10OP%,B10LRECL,F10KEYL%,b10key,B10KEYNUM%;
                              21000 IOPT = 2
                              IF IOPT = 2 THEN 22000 ELSE 23000
                              22000 '
                              22010 ' 22000-22999 - Option 2 -- DISPLAY a record.
                              22020 '
                              22030 IOPT=2 'Go display option number.
                              22050 B10OPCODE%=BGETGE%
                              22060 GOSUB 10100 'Go read the record.
                              22070 IF B10STATUS% <> 0 THEN 22190 'Branch if record not found.
                              LOCATE 21,1: PRINT B10OP%,B10LRECL,F10KEYL%,b10key,B10KEYNUM%;
                              MSG$ = USING$("#######",F10SLPAC#)
                              LOCATE 22,1: PRINT MSG$
                              22080 GOSUB 32000 'Go display verbage.
                              22090 GOSUB 33000 'Go display data.

                              Q0001 ' SAVE"C:F10INVC.INC",A
                              10003 '* 10000-10099 ** 01/01/2009 ** Subroutine to open file #10. ************
                              'DIM F10KLEN%(2),F10TYPE$(2),F10DUP$(2),F10KEYS$(2)
                              DIM F10DATA As DATABUF10
                              DIM F10POSB AS typPosBlk
                              DIM B10LRECL AS Integer
                              DIM F10NAME AS asciiz * 22
                              DIM B10KEY AS Asciiz * 22
                              DIM hFile AS LONG
                              LOCAL F10REC1 AS F10RECORD
                              F10NAME = "c:\pbdev\ICONTROL.DAT "
                              B10LRECL = 44
                              'Keylen,Typ,Dup,Field Name
                              F10KLEN%(0) = 10 'Key 0 Key Length
                              F10TYPE$(0) = "U" 'Key 0 Data Type (Upper Case Alphanumeric)
                              F10DUP$(0) = " " 'Key 0 DUP
                              F10KEYS$(0) = "Control Record" 'Key 0 Field Name
                              F10KLEN%(1) = 0 'Key 1 (No Key 1)
                              F10TYPE$(1) = "C"
                              F10DUP$(1) = " "
                              F10KEYS$(1) = "Key 1"
                              'Old DOS Code Btrieve
                              hFile = FREEFILE
                              'OPEN "NUL" AS #hFile LEN=B10LRECL 'BASIC open.
                              'FIELD #10, B10LRECL AS F10REC1$ ' <======== Note FIELD statement.
                              B10KEYNUM% = 0
                              B10KEY = F10NAME 'Set B10KEY as File Name for OPEN
                              F10KEYL% = LEN(F10NAME)+1 'Key Length for OPEN.
                              B10STATUS% = 0 'Initialize Status Code to 0.
                              B10LOCK$ = "N" 'Initialize LOCK
                              B10LOCKF$ = "N" 'Init Lock Flag
                              B10OPCODE%=BOPEN%: GOSUB 10110 'Go BTRIEVE open the file.
                              IF B10STATUS% = 0 THEN 10065 'ERROR occurred if Status <> 0
                              DBNAME$ = F10NAME$: BSTATUS% = B10STATUS%: BOPCODE% = B10OPCODE%: BKEY$ = B10KEY: GOSUB 700
                              10065 B10KEY = SPACE$(F10KEYL%) 'Init key field to blanks.
                              10099 RETURN
                              10100 '* 10100-10199 ** Subroutine to perform BTRIEVE I/O for file #10. ****
                              F10KEYL% = F10KLEN%(B10KEYNUM%)
                              10110 IF B10LOCK$ = "Y" THEN B10OP% = B10OPCODE% + BLOCKWN%: B10LOCKF$ = "Y": B10LOCK$ = "N" ELSE B10OP% = B10OPCODE%
                              IF B10OPCODE%=BINSERT% OR B10OPCODE%=BUPDATE% THEN GOSUB 10400
                              'B10FCBPTR = VARPTR(F10REC1) 'Get address of FCB.
                              B10STATUS% = BTRCALL(B10OP%,F10POSB,F10DATA,B10LRECL,B10KEY,F10KEYL%,B10KEYNUM%)
                              IF DEBUG$ <> "D" THEN 10180
                              MSG$ = USING$ ("File 10 I/O - Op=## Lock=! Stat=## Keyl=## Key=\ \ Keynm=#",B10OPCODE%,B10LOCKF$,B10STATUS%,LEN(B10KEY),B10KEY,B10KEYNUM%)
                              LOCATE 23,1: PRINT MSG$;
                              MSG$ = " Press ENTER to continue.": IBUFF$="Y": GOSUB 200: LOCATE 23,1: PRINT SPACE$(79);
                              10180 DBNAME$ = F10NAME: BSTATUS% = B10STATUS%: BOPCODE% = B10OPCODE%: BKEY$ = B10KEY
                              IF B10STATUS% <> 0 THEN 10198
                              IF B10OPCODE%>4 AND B10OPCODE%<14 THEN GOSUB 10300 'Get data into local variables.
                              10198 IF B10OPCODE% < 5 THEN B10LOCKF$ = "N"
                              10199 RETURN
                              10300 '* 10300-10399 ** File 10 - Random file buffer to local variables. *********
                              SREC1$ = F10REC1 'Get record from random file buffer.
                              F10SCNTL$ = MID$(SREC1$,1,10)
                              F10SNOPL# = CVD(MID$(SREC1$,11,8))
                              F10SNOIN# = CVD(MID$(SREC1$,19,8))
                              F10SLRNU! = CVI(MID$(SREC1$,27,2))
                              F10SLPAC# = CVD(MID$(SREC1$,29,8))
                              F10SLINV# = CVD(MID$(SREC1$,37,8))
                              Locate 18,1: print f10REC1;
                              10399 RETURN

                              Comment


                              • #35
                                Mike, if you look at the BTRCALL, I changed the variable F10DATA to F10REC1. Then I got the same results as before, "CONTROLREC" plus garbage.

                                I went back to the old programs and did a PRINT of the 44 Character Buffer and got the same thing. So the issue must be recognizing the numeric fields.

                                Roy

                                Comment


                                • #36
                                  One more thing. While the old code PRINT dispalyed the same thing as the new, the old code put the data into the proper variables and displayed OK. So there must be something going on with boundary addresses etc.
                                  Roy

                                  Comment


                                  • #37
                                    If the address of the buffer goes in the BTRCALL command, how do you link the UDT for fields to the buffer? Roy

                                    Comment


                                    • #38
                                      'Normally the keylength is the length of the keybuffer with fixed length records
                                      'You can write a few routines to make life easier and put the call to Btrieve in them:
                                      ' Examples only:
                                      ' UpdateIt(MyData$,KeyNumber)
                                      ' InsertIt(MyData$, KeyNumber)
                                      ' DeleteIt(Key$, KeyNumber)
                                      ' OpenIt(FileName$)
                                      'Write to Btrieve by updating the UDT data and make the call to btrieve
                                      'using the Op code you want to perform like %UPDATE or %INSERT
                                      'Read from Btrieve by using an Op code like %GetEqual, %GetNext,, %GetLast,, %GetFirst and the KeyNumber.
                                      'If you need to start with a record put the value in the zKeyBuffer and set the KeyNumber to use.

                                      'Note, I do not have nor have I seen Btrieve 7.
                                      'Please check that the call syntax is correct or post something to look at.


                                      Code:
                                      #COMPILE EXE
                                      #DIM ALL
                                      TYPE F10RECORD
                                        F10SCNTL AS STRING*10
                                        F10SNOPL AS DOUBLE
                                        F10SNOIN AS DOUBLE
                                        F10SLRNU AS INTEGER
                                        F10SLPAC AS DOUBLE
                                        F10SLINV AS DOUBLE
                                      END TYPE
                                      'Replace this with your DECLARE adding the LIB to
                                      'DECLARE FUNCTION BTRCALL Lib "wbtrv32.dll" (ByVal OpCode As Integer,          _
                                      DECLARE FUNCTION BTRCALL (BYVAL OpCode AS INTEGER,          _
                                                                 gBlock1 AS ASCIIZ,                _
                                                                 udt   AS F10Record,               _
                                                                 DataLength AS INTEGER,            _
                                                                 zKeyBuffer AS ASCIIZ,             _
                                                                 BYVAL Keylength AS INTEGER, _
                                                                 BYVAL KeyNumber AS INTEGER) AS INTEGER
                                      GLOBAL gBlock1 AS ASCIIZ * 129
                                      'Define btrieve operations
                                      %INSERT = 2: %UPDATE = 3: %GetEqual = 9: %RESET = 28
                                      FUNCTION PBMAIN () AS LONG
                                       
                                        LOCAL udt AS F10RECORD
                                        LOCAL result          AS INTEGER
                                        LOCAL op              AS INTEGER
                                        LOCAL zDataBuffer     AS ASCIIZ * 512
                                        LOCAL DataLength      AS INTEGER
                                        LOCAL zKeyBuffer      AS ASCIIZ * 65
                                        LOCAL KeyLength       AS INTEGER
                                        LOCAL KeyNumber       AS INTEGER
                                       
                                        zKeyBuffer = MKL$(1)
                                        Op = %GetEqual
                                        KeyNumber = 0
                                        KeyLength = LEN(zKeyBuffer)
                                        result = BTRCALL(Op%, gBlock1, udt, DataLength%, zKeyBuffer, KeyLength%, KeyNumber%)
                                         ? "Operation" + STR$(op) + " result" + STR$(result)
                                       
                                        udt.F10SNOPL = 1
                                        op = %UPDATE  'or %INSERT
                                        DataLength = LEN(udt)
                                        KeyLength =  LEN(zKeyBuffer)
                                        result = BTRCALL(Op%, gBlock1, udt, DataLength%, zKeyBuffer, KeyLength%, KeyNumber%)
                                        ? "Operation" + STR$(op) + " result" + STR$(result)
                                       
                                        op = %RESET   'close all BTRIEVE files
                                        result = BTRCALL(Op, gBlock1, udt, DataLength, zKeyBuffer, KeyLength, KeyNumber)
                                        ? "Operation" + STR$(op) + " result" + STR$(result)
                                        ? "Press any key to end";WAITKEY$
                                      END FUNCTION
                                      'Simulate DLL
                                      FUNCTION BTRCALL  (BYVAL Op AS INTEGER,          _
                                                         gBlock1 AS ASCIIZ,                _
                                                         udt AS F10Record,                 _
                                                         DataLength AS INTEGER,            _
                                                         zKeyBuffer AS ASCIIZ,             _
                                                         BYVAL Keylength AS INTEGER, _
                                                         BYVAL KeyNumber AS INTEGER) AS INTEGER
                                         SELECT CASE op
                                           CASE 0: ? "Open called"
                                           CASE 2: ? "Insert called"
                                           CASE 3: ? "Update called"
                                           CASE 9: ? "Get equal called"
                                           CASE ELSE: ? "Not defined here"
                                          END SELECT
                                      END FUNCTION
                                      Last edited by Mike Doty; 21 Dec 2008, 08:05 PM.
                                      CMD shortcut to open any location:
                                      %windir%\system32\cmd.exe /k " cd\ & x: & cd x:\xxxx
                                      Change to run as administrator
                                      How long is an idea? Write it down.

                                      Comment


                                      • #39
                                        Hi again Mike. I will work on this tomorrow. Thanks for your effort. The only thing I did not understand in this line of code was the "ZkeyBuffer = MKL$(1)" What/Where is MKL$(1) used?

                                        On another note. I ran the old program and printed out the results of the old returned data string and it is EXACTLY the same as the new string, with the same characters in the same position, (Same data in both .DAT files). The difference is the old CVD converts the data to a double byte variable, while the new data CVD gives a -2.nnnnnnnnnnn Ennn.

                                        Could this be a problem with data offset, or a difference in how PB uses CVD?

                                        ROy

                                        Comment


                                        • #40
                                          That was only an example finding a value with a binary key of 1.
                                          Don't know about the double precision values, sorry.
                                          Sounds like you are getting close.
                                          CMD shortcut to open any location:
                                          %windir%\system32\cmd.exe /k " cd\ & x: & cd x:\xxxx
                                          Change to run as administrator
                                          How long is an idea? Write it down.

                                          Comment

                                          Working...
                                          X