Rob Wubs

Absent Member.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2011-01-21
21:09
4270 views
[Migrated content. Thread originally posted on 21 January 2011]
Can someone tell me how to bind data from ISAM files to windows controls in Visual Cobol? (not with the help of a third-party component).At the launch of Visual Cobol R3 I asked this and I was told that I can not directly bind isam data to a user control. Now I'm looking for the best alternative/solution.
At this moment we (Centric) use COBOL (NetExpress 4) and Visual Basic 6 (Front End) for developing payroll software. We use COBjects (a third party component that is not supported anymore) for getting data from ISAM files and bind it to user controls with the help of ADO records. The batch processes (calculating) are written in COBOL.
For the future we want to use Visual Cobol replacing Visual Basic 6. We see so much advantages in using Visual Cobol!
1 Solution
Accepted Solutions
Chris Glazier

Micro Focus Expert
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2011-01-21
23:10
Here is a better example.
This is a complete COBOL Winform program that has a single DataViewGrid control on the form.
This is a complete COBOL Winform program that has a single DataViewGrid control on the form.
$set SQL(DBMAN=ADO)
class-id TestDataBind.Form1 is partial
inherits type System.Windows.Forms.Form.
working-storage section.
EXEC SQL include sqlca END-EXEC.
EXEC ADO declare customers datatable
(
CustName string(30) not null,
CustCompany string(30) not null,
CustPhone string(20) not null
)
End-Exec
EXEC ADO declare cust_info dataset for customers
save schema to "cust_info.xsd"
END-EXEC
.
01 CustomerDataset type System.Data.DataSet.
01 tmpDataset object reference.
method-id NEW.
procedure division.
invoke self::InitializeComponent
invoke self::fillGrid()
set dataGridView1::DataSource to CustomerDataset::Tables::Item("Customers")
goback.
end method.
method-id fillGrid.
local-storage section.
01 lsCustName pic x(30).
01 lsCustCompany pic x(30).
01 lsCustPhone pic x(20).
procedure division.
EXEC ADO Initialize dataset
returning :tmpDataset
END-EXEC
set CustomerDataset to tmpDataset as type System.Data.DataSet.
*> The following could be a read from an ISAM file to get data instead of a move
move "Chris Glazier" to lsCustName
move "Micro Focus" to lsCustCompany
move "(800) 555-1212" to lsCustPhone
EXEC ADO
insert into customers
values (:lsCustName,
:lsCustCompany,
:lsCustPhone)
END-EXEC
move "John Smith" to lsCustName
move "Smith Plumbing" to lsCustCompany
move "(603) 555-9999" to lsCustPhone
EXEC ADO
insert into customers
values (:lsCustName,
:lsCustCompany,
:lsCustPhone)
END-EXEC
move "Sue Jackson" to lsCustName
move "Jackson Software" to lsCustCompany
move "(203) 555-7777" to lsCustPhone
EXEC ADO
insert into customers
values (:lsCustName,
:lsCustCompany,
:lsCustPhone)
END-EXEC
EXEC ADO
Accept changes for all datatables
END-EXEC
EXEC ADO
unbind
END-EXEC
exit method.
end method.
end class.
6 Replies
Chris Glazier

Micro Focus Expert
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2011-01-21
21:19
You need to get the ISAM data into a .NET bindable object such as an ADO.NET dataset or an array.
Visual COBOL provides for ADO.NET syntax directly allowing you to define and manipulate dataset objects using COBOL syntax. Look in the documentation under Database Access->EXEC ADO syntax.
Example:
Visual COBOL provides for ADO.NET syntax directly allowing you to define and manipulate dataset objects using COBOL syntax. Look in the documentation under Database Access->EXEC ADO syntax.
Example:
EXEC SQL include sqlca END-EXEC
*> Declare the table that will be used
*> to represent the patron data
EXEC ADO declare patrons datatable
(
patron_number int16 default 0,
first_name string(10) not null,
last_name string(12) not null,
street_address string(20) not null,
)
End-Exec
*> Define all tables in dataset and save
*> the schema to an XML file
EXEC ADO declare patron_info dataset for patrons
save schema to "patron_info.xsd"
END-EXEC
.
01 Patron-Dataset object reference DataSet.
01 tmp-DataSet object reference.
Procedure Division returning Patron-Dataset.
*> Create the dataset
EXEC ADO
Initialize dataset returning :tmp-Dataset
END-EXEC
set Patron-Dataset to tmp-Dataset as DataSet
*> Read thru ISAM file pulling outrecords and add them to the dataset as follows:
EXEC ADO
insert into patrons
values (:ls-patron-number,
:ls-first-name,
:ls-last-name,
:ls-street-address,
END-EXEC
*> Once you have added all records commit changes
EXEC ADO
Accept changes for all datatables
END-EXEC
*> Unbind from the dataset.
EXEC ADO
unbind
END-EXEC
Chris Glazier

Micro Focus Expert
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2011-01-21
23:10
Here is a better example.
This is a complete COBOL Winform program that has a single DataViewGrid control on the form.
This is a complete COBOL Winform program that has a single DataViewGrid control on the form.
$set SQL(DBMAN=ADO)
class-id TestDataBind.Form1 is partial
inherits type System.Windows.Forms.Form.
working-storage section.
EXEC SQL include sqlca END-EXEC.
EXEC ADO declare customers datatable
(
CustName string(30) not null,
CustCompany string(30) not null,
CustPhone string(20) not null
)
End-Exec
EXEC ADO declare cust_info dataset for customers
save schema to "cust_info.xsd"
END-EXEC
.
01 CustomerDataset type System.Data.DataSet.
01 tmpDataset object reference.
method-id NEW.
procedure division.
invoke self::InitializeComponent
invoke self::fillGrid()
set dataGridView1::DataSource to CustomerDataset::Tables::Item("Customers")
goback.
end method.
method-id fillGrid.
local-storage section.
01 lsCustName pic x(30).
01 lsCustCompany pic x(30).
01 lsCustPhone pic x(20).
procedure division.
EXEC ADO Initialize dataset
returning :tmpDataset
END-EXEC
set CustomerDataset to tmpDataset as type System.Data.DataSet.
*> The following could be a read from an ISAM file to get data instead of a move
move "Chris Glazier" to lsCustName
move "Micro Focus" to lsCustCompany
move "(800) 555-1212" to lsCustPhone
EXEC ADO
insert into customers
values (:lsCustName,
:lsCustCompany,
:lsCustPhone)
END-EXEC
move "John Smith" to lsCustName
move "Smith Plumbing" to lsCustCompany
move "(603) 555-9999" to lsCustPhone
EXEC ADO
insert into customers
values (:lsCustName,
:lsCustCompany,
:lsCustPhone)
END-EXEC
move "Sue Jackson" to lsCustName
move "Jackson Software" to lsCustCompany
move "(203) 555-7777" to lsCustPhone
EXEC ADO
insert into customers
values (:lsCustName,
:lsCustCompany,
:lsCustPhone)
END-EXEC
EXEC ADO
Accept changes for all datatables
END-EXEC
EXEC ADO
unbind
END-EXEC
exit method.
end method.
end class.
spgennard

Micro Focus Expert
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2011-01-22
00:20
An alternative approach is to populate the DataTable yourself, which
can be done relatively easy, for example:
can be done relatively easy, for example:
class-id DataBoundGrid.Form1 is partial
inherits type System.Windows.Forms.Form.
working-storage section.
method-id NEW.
procedure division.
invoke self::InitializeComponent
goback.
end method.
method-id Form1_Load final private.
procedure division using by value sender as object e as type System.EventArgs.
set self::dataGridView1::DataSource to self::GetDataSet()
end method.
method-id GetDataSet.
local-storage section.
01 dataColumn type System.Data.DataColumn.
01 dataRow type System.Data.DataRow.
procedure division returning dataset as type System.Data.DataTable.
set dataset to new type System.Data.DataTable()
set dataColumn to new type System.Data.DataColumn()
set dataColumn::DataType to type of System.String
set dataColumn::ColumnName to "CustName"
invoke dataset::Columns::Add(dataColumn)
set dataColumn to new type System.Data.DataColumn()
set dataColumn::DataType to type of System.String
set dataColumn::ColumnName to "CustCompany"
invoke dataset::Columns::Add(dataColumn)
set dataColumn to new type System.Data.DataColumn()
set dataColumn::DataType to type of System.String
set dataColumn::ColumnName to "CustPhone"
invoke dataset::Columns::Add(dataColumn)
*> populate the grid..
set dataRow to dataset::NewRow()
set dataRow::Item("CustName") to "Chris Glazier"
set dataRow::Item("CustCompany") to "Micro Focus"
set dataRow::Item("CustPhone") to "(800) 555-1212"
invoke dataset::Rows::Add(dataRow)
set dataRow to dataset::NewRow()
set dataRow::Item("CustName") to "John Smith"
set dataRow::Item("CustCompany") to "Smith Plumbing"
set dataRow::Item("CustPhone") to "(603) 555-9999"
invoke dataset::Rows::Add(dataRow)
set dataRow to dataset::NewRow()
set dataRow::Item("CustName") to "Sue Jackson"
set dataRow::Item("CustCompany") to "Jackson Software"
set dataRow::Item("CustPhone") to "(203) 555-7777"
invoke dataset::Rows::Add(dataRow)
end method.
end class.
MichaelB1

Micro Focus Frequent Contributor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2011-01-22
07:37
One other alternative is to use the property all clause and define a class that can be used to create a Data Transfer Object (DTO). You then combine this with the .NET Generic List/Collection capability to create a Collection.
Assuming this is a simple record layout for the file:
Define a class with the same record layout as such using the PROPERTY ALL clause.
In your application (after adding a reference to the Class you created and built):
You use the FileList Collection you've created for the data binding. The property all clause exposes all the items including the group level as properties which allows you to selectively expose them to columns in a grid or other controls.
Here is a little video of it working
Notes:
- Don't forget to add your DTO class and System.Collections.Generic to your namespaces in your references (References tab in Project Properties).
- Also...when creating your DTO it is simple to just copy the original record layout but make sure you remove the hyphens or replace them with _ in the data names if you plan to use the DTO class with other .NET languages like C#...the hyphens don't mix well with C#. Visual COBOL will accept both hyphens and underscores in data names if using the default or Micro Focus dialect.
Hope this helps...please feel free to ask questions....
Assuming this is a simple record layout for the file:
01 original-file-rec.
05 fld1 pic x(10).
05 fld2 pic x(10).
05 fld3 pic s9(4) comp.
Define a class with the same record layout as such using the PROPERTY ALL clause.
class-id FileRecDTO.
working-storage section.
01 FileRec property all.
05 fld1 pic x(10).
05 fld2 pic x(10).
05 fld3 pic s9(4) comp.
end class.
In your application (after adding a reference to the Class you created and built):
working-storage section.
01 FileDTOObj type FileRecDTO.
01 FileList type List[type FileRecDTO].
01 original-file-rec.
05 fld1 pic x(10).
05 fld2 pic x(10).
05 fld3 pic s9(4) comp.
01 idx binary-long.
01 FileRecDTOObject type FileRecDTO.
01 FileList type List[type FileRecDTO]. *> Create a Collection/List of FileRecDTO objects
Procedure division.
set FileList to new List[type FileRecDTO]
*> Process Records...these are just sample move/set statements to create some test data
perform varying idx from 1 by 1 until idx > 8
set fld1 to "String1 " & idx
set fld2 to "String2 " & idx
set fld3 to idx
set FileDTOObj to new FileRecDTO()
set FileDTOObj::FileRec to original-file-rec
invoke FileList::Add(FileDTOObj)
end-perform
set dataGridView1::AutoGenerateColumns to false *> This example assumes you've created the columns in advance or you could create them at runtime
set dataGridView1::DataSource to FileList
You use the FileList Collection you've created for the data binding. The property all clause exposes all the items including the group level as properties which allows you to selectively expose them to columns in a grid or other controls.
Here is a little video of it working
Notes:
- Don't forget to add your DTO class and System.Collections.Generic to your namespaces in your references (References tab in Project Properties).
- Also...when creating your DTO it is simple to just copy the original record layout but make sure you remove the hyphens or replace them with _ in the data names if you plan to use the DTO class with other .NET languages like C#...the hyphens don't mix well with C#. Visual COBOL will accept both hyphens and underscores in data names if using the default or Micro Focus dialect.
Hope this helps...please feel free to ask questions....
Scot Nielsen

Absent Member.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2011-01-22
13:52
And another alternative 🙂 this one implements IEnumerable which moves through a file which we can then set to the ItemsSource property of a WPF listbox.
email me if you want the full project for this (scot.nielsen@microfocus.com).
email me if you want the full project for this (scot.nielsen@microfocus.com).
class-id WPFApplication1.Window1 is partial
inherits type System.Windows.Window.
working-storage section.
method-id NEW.
procedure division.
invoke self::InitializeComponent()
goback.
end method.
method-id Window_Loaded final private.
procedure division using by value sender as object e as type System.Windows.RoutedEventArgs.
set listBox1::ItemsSource to new FileDataSource
end method.
end class.
class-id FileDataSource implements type System.Collections.IEnumerator,
type System.Collections.IEnumerable
.
select optional a-file assign "indexed.dat"
organization indexed
record key is the-key
access is dynamic
.
fd a-file.
01 the-record.
03 the-key pic x(10).
working-storage section.
01 at-end condition-value value false.
method-id New.
local-storage section.
procedure division.
delete file a-file
open i-o a-file
move "banana" to the-key
write the-record
move "orange" to the-key
write the-record
move "kiwi" to the-key
write the-record
move "apple" to the-key
write the-record
move "tomato" to the-key
write the-record
move "apple" to the-key
write the-record
move "passion" to the-key
write the-record
move "grape" to the-key
write the-record
move "mango" to the-key
write the-record
move "pineapple" to the-key
write the-record
move spaces to the-key
start a-file key > the-key
goback.
end method.
*> Automatically inserted Methods from System.Collections.IEnumerable
method-id GetEnumerator for type System.Collections.IEnumerable.
procedure division returning return-item as type System.Collections.IEnumerator.
set return-item to self
end method.
*> End Methods from System.Collections.IEnumerable
*> Automatically inserted Methods from System.Collections.IEnumerator
method-id MoveNext.
procedure division returning return-item as condition-value.
if not at-end
read a-file next record
at end
set at-end to true
end-read
end-if
set return-item to not at-end
end method.
method-id Reset.
procedure division.
move spaces to the-key
start a-file key > the-key
end method.
method-id get property Current.
procedure division returning return-item as object.
set return-item to the-key
end method.
*> End Methods from System.Collections.IEnumerator
end class.
Robert Zijl

Absent Member.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2011-02-01
08:33
On behalf of my colleague, thanks a lot!
I am currently trying this out. Goal is to read / write a native ISAM file, after reading turn it into an ADO recordset, bind a few controls, alter values and afterwards write from ADO to ISAM.
I am a native VB developer for over ten years so I'll have to learn some COBOL while trying to get this to work.
I am currently trying this out. Goal is to read / write a native ISAM file, after reading turn it into an ADO recordset, bind a few controls, alter values and afterwards write from ADO to ISAM.
I am a native VB developer for over ten years so I'll have to learn some COBOL while trying to get this to work.