I need to define an array within a structure. I tried "Txt As Variant" and "txt() As Variant" and neither work when try to use Struct.Txt as an array. What is the correct way to define an array within a structure in Extra Basic? It works in VB but not Extra. Please point me in the right direction.
' Example Data
Type RWText
Cmd As String
FnameA As String
FnameB As String
Value As Integer
Txt As Variant
Src As String
Dst As String
End Type
Dim Struct As RWText
Struct.Txt(1) = "test"#type#Attachmate#MainframeAccess#Extra!#structure#Extra!X-tremeHi David;
something like below sample ? The code declares a custom data type named "Employee". It has three fields: name, id and salary. Each field is of a specific data type (string, integer and single precision floating point).n the Main subroutine, an array of type "Employee" is declared with 4 elements, called "employees". The first two elements of the array are then populated with employee data (name, id, and salary).
Finally, the values of the first two elements of the "employees" array are printed to the screen.
TYPE Employee
name AS STRING * 20
id AS INTEGER
salary AS SINGLE
END TYPE
Sub Main
DIM employees(4) AS Employee
employees(0).name = "John Doe"
employees(0).id = 12345
employees(0).salary = 55000.0
employees(1).name = "Jane Doe"
employees(1).id = 12346
employees(1).salary = 60000.0
PRINT employees(0).name, employees(0).id, employees(0).salary
PRINT employees(1).name, employees(1).id, employees(1).salary
End Sub
cheers
Hi David;
something like below sample ? The code declares a custom data type named "Employee". It has three fields: name, id and salary. Each field is of a specific data type (string, integer and single precision floating point).n the Main subroutine, an array of type "Employee" is declared with 4 elements, called "employees". The first two elements of the array are then populated with employee data (name, id, and salary).
Finally, the values of the first two elements of the "employees" array are printed to the screen.
TYPE Employee
name AS STRING * 20
id AS INTEGER
salary AS SINGLE
END TYPE
Sub Main
DIM employees(4) AS Employee
employees(0).name = "John Doe"
employees(0).id = 12345
employees(0).salary = 55000.0
employees(1).name = "Jane Doe"
employees(1).id = 12346
employees(1).salary = 60000.0
PRINT employees(0).name, employees(0).id, employees(0).salary
PRINT employees(1).name, employees(1).id, employees(1).salary
End Sub
cheers
Thank you for the advise, but I don't want the whole structure to be an Array. I only need one item to be an array. I'm thinking I'll have to do the array outside of the structure.
Thank you for the advise, but I don't want the whole structure to be an Array. I only need one item to be an array. I'm thinking I'll have to do the array outside of the structure.
Hi David,
correct, I can't get an array to work inside a Type either.
Question why are you not using an array outside the type?
e.g.
Type RWText
Cmd As String
FNameA As String
FnameB As String
Value As Integer
TxtUBound As Integer 'Size of the array you need
Src As String
Dst As String
End Type
Sub main
Dim myRWText as RWText
myRWText.TxtUBound = 2
Dim RWText_Txt(myRWText.TxtUBound) as Sting
RWText_Txt(1) = "Hello"
RWText_Txt(2) = "world"
End Sub
What is the goal of this function you are working on?
Tom
Hi David,
correct, I can't get an array to work inside a Type either.
Question why are you not using an array outside the type?
e.g.
Type RWText
Cmd As String
FNameA As String
FnameB As String
Value As Integer
TxtUBound As Integer 'Size of the array you need
Src As String
Dst As String
End Type
Sub main
Dim myRWText as RWText
myRWText.TxtUBound = 2
Dim RWText_Txt(myRWText.TxtUBound) as Sting
RWText_Txt(1) = "Hello"
RWText_Txt(2) = "world"
End Sub
What is the goal of this function you are working on?
Tom
Good afternoon, Tom,
On my other bloated macro there are a number of time I need to do file functions and figured i would just have a FileOps() function to be used for all my read, write, etc. needs. The text array was for any data being written out or read. This is rudimentary but here's my function. Don't judge me yet, I'm still playing and figuring out best approach.
Type RWText
Cmd As String
FNameA As String
FnameB As String
Value As Integer
Src As String
Dst As String
End Type
Declare Function FileOps(Struct As RWText, RWText_Txt() As String)
Sub Main ' testing macro
Dim Struct As RWText
Dim RWText_Txt(2) As String
Struct.Value = 0
Struct.Cmd = "W"
Struct.FnameA = "Test1.txt"
Struct.FnameB = ""
Struct.Src = "H:\\Dev\\"
Struct.Dst = ""
RWText_Txt(0) = "Hello"
RWText_Txt(1) = "world"
Call FileOps(Struct, RWText_Txt)
End Sub
Function FileOps(Struct As RWText, RWText_Txt() As String)
Dim fnum
Dim x As Integer
On error goto ExitSafe
Select case Struct.Cmd
Case "C" ' Check File
If Dir(Struct.Src & Struct.FnameA) <> "" Then
msgbox "File " & Struct.FnameA & " exists."
Else
msgbox "File " & Struct.FnameA & " doesn't exist."
End If
Case "W" ' Write 'overwrite data in whole file'
x = 0
fnum = FreeFile()
Open str(Struct.Src & Struct.FnameA) For Output As #fnum
Do Until x = UBOUND(RWText_Txt)
Write #fnum, RWText_Txt(x)
x = x + 1
Loop
Close #fnum
Case "A" ' Write 'Append' to add new lines
x = 0
fnum = FreeFile()
Open str(Struct.Src & Struct.FnameA) For Append As #fnum
Do Until x = UBOUND(RWText_Txt)
Write #fnum, RWText_Txt(x)
x = x + 1
Loop
Close #fnum
Case "R" ' Read
Dim strLine As String
x=0
Open Struct.Src & Struct.FnameA For Input As #1
Do Until EOF(1)
Line Input #1, strLine
x = x + 1
RWText_Txt(x) = strLine
Loop
Close #1
Case "CP" ' copy file
FileCopy Struct.Src & Struct.FnameA, Struct.Dst & Struct.FnameB
Case "D"
' Delete
Case Else
msgbox "thats all"
end select
ExitSafe:
Close #fnum
End Function
Good afternoon, Tom,
On my other bloated macro there are a number of time I need to do file functions and figured i would just have a FileOps() function to be used for all my read, write, etc. needs. The text array was for any data being written out or read. This is rudimentary but here's my function. Don't judge me yet, I'm still playing and figuring out best approach.
Type RWText
Cmd As String
FNameA As String
FnameB As String
Value As Integer
Src As String
Dst As String
End Type
Declare Function FileOps(Struct As RWText, RWText_Txt() As String)
Sub Main ' testing macro
Dim Struct As RWText
Dim RWText_Txt(2) As String
Struct.Value = 0
Struct.Cmd = "W"
Struct.FnameA = "Test1.txt"
Struct.FnameB = ""
Struct.Src = "H:\\Dev\\"
Struct.Dst = ""
RWText_Txt(0) = "Hello"
RWText_Txt(1) = "world"
Call FileOps(Struct, RWText_Txt)
End Sub
Function FileOps(Struct As RWText, RWText_Txt() As String)
Dim fnum
Dim x As Integer
On error goto ExitSafe
Select case Struct.Cmd
Case "C" ' Check File
If Dir(Struct.Src & Struct.FnameA) <> "" Then
msgbox "File " & Struct.FnameA & " exists."
Else
msgbox "File " & Struct.FnameA & " doesn't exist."
End If
Case "W" ' Write 'overwrite data in whole file'
x = 0
fnum = FreeFile()
Open str(Struct.Src & Struct.FnameA) For Output As #fnum
Do Until x = UBOUND(RWText_Txt)
Write #fnum, RWText_Txt(x)
x = x + 1
Loop
Close #fnum
Case "A" ' Write 'Append' to add new lines
x = 0
fnum = FreeFile()
Open str(Struct.Src & Struct.FnameA) For Append As #fnum
Do Until x = UBOUND(RWText_Txt)
Write #fnum, RWText_Txt(x)
x = x + 1
Loop
Close #fnum
Case "R" ' Read
Dim strLine As String
x=0
Open Struct.Src & Struct.FnameA For Input As #1
Do Until EOF(1)
Line Input #1, strLine
x = x + 1
RWText_Txt(x) = strLine
Loop
Close #1
Case "CP" ' copy file
FileCopy Struct.Src & Struct.FnameA, Struct.Dst & Struct.FnameB
Case "D"
' Delete
Case Else
msgbox "thats all"
end select
ExitSafe:
Close #fnum
End FunctionHi David,
Not wanting to come across the wrong way here, but I don't like that idea at all.
If I was in your shoes I would look to perform your file operations using the Microsoft.Scripting.Runtime library's FileSystemObject object. That should allow you to perform most of the various operations in one line of code. Writing to file may take some extra effort.
Unfortunately as ebedit.exe doesn't have any usable intelisense or object browser, normally when I'm looking to use COM/OLE objects from other libraries I employ VBA to allow me to browse the objects and get the values for constants etc. I just add the relevant reference in the VBA project and boom. Then in my Extra! BAsic macro I just dim everything as a generic Object and replace and constants used in the code to the value of the constant as retrieved from VBA.
e.g. Here is a function to write to file, it will create the file it it doesn't exist and will append to file if it does exist.
Declare Function myWriteToFile(TempFile as String, Overwrite as Integer, myText as String) as Integer
Sub Main
'Extra! objects
Dim mySystem as Object, mySession as Object, myScreen as Object
'File related variables
Dim Overwrite as Integer, TempFile as String, retC as Integer
'Create the Extra! objects
Set mySystem = CreateObject("EXTRA.System")
Set mySession = mySystem.ActiveSession
Set myScreen = mySession.Screen
'*** get the string we want to write to file
'Get the screen into a string
myScreenText = ""
i = 1
For i = 1 to 24
myScreenText = MyScreenText & myScreen.GetString (i,1,80) & Chr$(13) & Chr$(10)
Next i
'*** Get this string to disk !!!
'Set tempFile name
TempFile = "c:\\temp\\HelloWorld.David"
'Overwite my file if is exists
Overwrite = 0
retC = myWriteToFile(TempFile, Overwrite, myScreenText)
'*** Check the Return Code
If retC = 1 then
Msgbox "File Created"
ElseIf retC = 2 then
Msgbox "Text appended to existing file"
Else
Msgbox "Text not saved to file"
End If
End Sub
Function myWriteToFile(TempFile as String, Overwrite as Integer, myText as String) as Integer
'Create File related objects
Dim myFSO as Object, myFile as Object
'Create the FileSystemObject object
Set myFSO = CreateObject("Scripting.FileSystemObject")
'Check if file does not exist or we want to overwrite
If (myFSO.FileExists(TempFile) = 0 or Overwrite = -1) then
Set myFile = myFSO.CreateTextFile(TempFile)
'Write the screen to file
myFile.WriteLine myText
myFile.Close
myWriteToFile = 1
'If files exist and Overwrite is 0, then append
ElseIf (myFSO.FileExists(TempFile) = -1 and Overwrite = 0) then
Set myFile = myFSO.OpenTextFile(TempFile, 8, True, 0)
myFile.WriteLine myText
myWriteToFile = 2
Else
myWriteToFile = 0
End If
End FunctionNote: The above will add a blank line between writes, if you don't want the blank file, then use myFile.Write mystring, and you can control the trailing CRFL while you build the string you want to write to file.
Using an array to store the file data is IMHO a bad idea, populating the array and parsing the array is expensive. How will you know the size of the array starting off, if you have to redim preserve it then it becomes very expensive. If you are writing to disk in a loop while indexing through the array then it's even more expensive.
Here is a screenshot of the FSO object methods, as you can see, almost all one-line calls, so little point in creating a function to handle everything, because if just adds to volume of code you have to maintain.

Another thing to watch out for when using external objects is the variable types, e.g. Extra! Basic doesn't do Boolean, so just declare as integer. In general -1 == true and 0 == false, however at one point Windows was returning true as 1, so to be on the safe side if you encounter a Boolean, check if it's 0, if it is not then it's true !! :-)
Similar with TextStream, I just using String, I think the max length for a string is 65K bytes, so if you are reading or writing anything longer you may be out of luck.
If you do go this route, you will likely need a second function myReadFile, so you can check if it exists and return the contents as a string.
Hi David,
Not wanting to come across the wrong way here, but I don't like that idea at all.
If I was in your shoes I would look to perform your file operations using the Microsoft.Scripting.Runtime library's FileSystemObject object. That should allow you to perform most of the various operations in one line of code. Writing to file may take some extra effort.
Unfortunately as ebedit.exe doesn't have any usable intelisense or object browser, normally when I'm looking to use COM/OLE objects from other libraries I employ VBA to allow me to browse the objects and get the values for constants etc. I just add the relevant reference in the VBA project and boom. Then in my Extra! BAsic macro I just dim everything as a generic Object and replace and constants used in the code to the value of the constant as retrieved from VBA.
e.g. Here is a function to write to file, it will create the file it it doesn't exist and will append to file if it does exist.
Declare Function myWriteToFile(TempFile as String, Overwrite as Integer, myText as String) as Integer
Sub Main
'Extra! objects
Dim mySystem as Object, mySession as Object, myScreen as Object
'File related variables
Dim Overwrite as Integer, TempFile as String, retC as Integer
'Create the Extra! objects
Set mySystem = CreateObject("EXTRA.System")
Set mySession = mySystem.ActiveSession
Set myScreen = mySession.Screen
'*** get the string we want to write to file
'Get the screen into a string
myScreenText = ""
i = 1
For i = 1 to 24
myScreenText = MyScreenText & myScreen.GetString (i,1,80) & Chr$(13) & Chr$(10)
Next i
'*** Get this string to disk !!!
'Set tempFile name
TempFile = "c:\\temp\\HelloWorld.David"
'Overwite my file if is exists
Overwrite = 0
retC = myWriteToFile(TempFile, Overwrite, myScreenText)
'*** Check the Return Code
If retC = 1 then
Msgbox "File Created"
ElseIf retC = 2 then
Msgbox "Text appended to existing file"
Else
Msgbox "Text not saved to file"
End If
End Sub
Function myWriteToFile(TempFile as String, Overwrite as Integer, myText as String) as Integer
'Create File related objects
Dim myFSO as Object, myFile as Object
'Create the FileSystemObject object
Set myFSO = CreateObject("Scripting.FileSystemObject")
'Check if file does not exist or we want to overwrite
If (myFSO.FileExists(TempFile) = 0 or Overwrite = -1) then
Set myFile = myFSO.CreateTextFile(TempFile)
'Write the screen to file
myFile.WriteLine myText
myFile.Close
myWriteToFile = 1
'If files exist and Overwrite is 0, then append
ElseIf (myFSO.FileExists(TempFile) = -1 and Overwrite = 0) then
Set myFile = myFSO.OpenTextFile(TempFile, 8, True, 0)
myFile.WriteLine myText
myWriteToFile = 2
Else
myWriteToFile = 0
End If
End FunctionNote: The above will add a blank line between writes, if you don't want the blank file, then use myFile.Write mystring, and you can control the trailing CRFL while you build the string you want to write to file.
Using an array to store the file data is IMHO a bad idea, populating the array and parsing the array is expensive. How will you know the size of the array starting off, if you have to redim preserve it then it becomes very expensive. If you are writing to disk in a loop while indexing through the array then it's even more expensive.
Here is a screenshot of the FSO object methods, as you can see, almost all one-line calls, so little point in creating a function to handle everything, because if just adds to volume of code you have to maintain.

Another thing to watch out for when using external objects is the variable types, e.g. Extra! Basic doesn't do Boolean, so just declare as integer. In general -1 == true and 0 == false, however at one point Windows was returning true as 1, so to be on the safe side if you encounter a Boolean, check if it's 0, if it is not then it's true !! :-)
Similar with TextStream, I just using String, I think the max length for a string is 65K bytes, so if you are reading or writing anything longer you may be out of luck.
If you do go this route, you will likely need a second function myReadFile, so you can check if it exists and return the contents as a string.
Sorry for my slow reply I'm back to working doubles again due to a shortage of foremen, this was extremely helpful and I'm back at re-coding all my file operations. Since I don't have an IDE with decent intelisense, I just ordered myself a copy of "VB & VBA in a Nutshell: The Language" from O’Reilly books. Are there any other books you would recommend? Later tonight I'm going to post a different question about hotspots that I believe is specific to Extra X-treme. Thank you again, I greatly apricate the directions you have pointed me.
Sorry for my slow reply I'm back to working doubles again due to a shortage of foremen, this was extremely helpful and I'm back at re-coding all my file operations. Since I don't have an IDE with decent intelisense, I just ordered myself a copy of "VB & VBA in a Nutshell: The Language" from O’Reilly books. Are there any other books you would recommend? Later tonight I'm going to post a different question about hotspots that I believe is specific to Extra X-treme. Thank you again, I greatly apricate the directions you have pointed me.
Hi David,
in terms of intelisense, you could use VB6 or a newer Visual Studio.
As for books, invariably if I can't copy and paste it, it sounds like a lot of work :-)..
e.g. searching on Google for
VBA File object
gives several relevant results.
Tom