Quantcast
Channel: Visual COBOL Knowledge Base
Viewing all 214 articles
Browse latest View live

Error 2738 shown during installation of Visual COBOL

$
0
0
Current Revision posted to Visual COBOL Knowledge Base by Kim.Hoskin on 9/22/2015 1:09:44 PM

Problem

Error 2738 shown during installation of Visual COBOL.

Full text shown in the Visual COBOL Installer is :

The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2738.

Resolution:

This is a Windows installer error, caused due to the Windows VBscript component not being enabled on the machine correctly. The Visual COBOL Product installer requires VBScript to be enabled.

To resolve, ensure that the vbscript.dll is registered into the Windows Global Assembly Cache (GAC) of the Windows Operating system, using command regsvr32.

This Microsoft dll file is usually located in path %windir%\system32\). 

See also the Microsoft MSDN webpage: http://msdn.microsoft.com/en-us/library/aa372835(v=vs.85).aspx

This explains that error code 2738 means: 

Could not access VBScript run time for custom action [2].  This usually means the vbscript.sll is not present or installed correctly, or being blocked by a Firewall/anti-virus type application.


Is there a limit to how many source files can be stored in a Visual COBOL for Eclipse project?

$
0
0
Current Revision posted to Visual COBOL Knowledge Base by Kim.Hoskin on 9/22/2015 1:10:40 PM

Problem

Is there a limit to how many source files can be stored in a Visual COBOL for Eclipse project?

 
Resolution:

There is no limit apart from that the Eclipse IDE shipped with Visual COBOL for Eclipse is a 32bit process and has a 2GB process limit.

For a baseline comparison, the Visual COBOL product's source code consists of over 6500 source files in about 40 projects and the Eclipse IDE can handle this without problem. It’s a matter of how things are organised rather than an absolute number.

How to uninstall MF COBOL Server from the command line?

$
0
0
Current Revision posted to Visual COBOL Knowledge Base by MF_Fano on 10/6/2015 5:28:57 PM

Problem:

How to uninstall MF COBOL Server silently from the command line?

Resolution:

You may use the same setup file that was used to install MF COBOL Server to uninstall the same product from an elevated command prompt:
start /wait <setup-file-exe> /quiet /uninstall

where <setup-file-exe> would be for example:

  • cs2010_22.exe for COBOL Server 2010 version 2.2
  • cs2012_221.exe for COBOL Server 2012 version 2.2 Update 1
  • cs2013_222.exe for COBOL Server 2013 version 2.2 Update 2

Please take note that the uninstallation process of COBOL Server does not uninstall MF License Manager automatically. In order to uninstall License Manager, you will need to know its product GUID. This is a long string that is enclosed within braces, e.g. {C4920323-C34A-4462-9C3E-BA0325BBD9BA}

The product GUID is different from a version of COBOL Server to another, and you may find it from the Windows Registry:

  1. Open Windows Registry (regedit.exe)
  2. Go to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
  3. Right-click on the Uninstall key
  4. Click on Find...
  5. Enter License Manager in the Find what field
  6. Click on Find Next
  7. Double-click on UninstallString in the right pane to copy the product GUID that is enclosed between braces

Once the product GUID is determined, you may run the following command to uninstall License Manager:
start /wait msiexec /qn /x <product-guid>

Examples:

To uninstall License Manager for COBOL Server 2013 version 2.2 Update 2 on a 64-bit Windows platform:
start /wait msiexec /qn /x {C4920323-C34A-4462-9C3E-BA0325BBD9BA}

To uninstall License Manager for COBOL Server 2010 version 2.1 Update 1 on a 32-bit Windows platform:
start /wait msiexec /qn /x {7548D756-87E6-4C2A-9CC2-D9270564BEFB}

Unable to apply HotFix 7 or higher on COBOL Server 2.2 Update 2

$
0
0
Current Revision posted to Visual COBOL Knowledge Base by MF_Fano on 10/6/2015 6:25:08 PM

Problem:

The installation of HotFix 7 or higher fails with the following error message:

Fix setup issue(s) and retry. For more information see the log file.

0x81f40001 - Micro Focus COBOL Server 2013 has been detected but needs to be upgraded to the R2 version. R2 can be downloaded from the SupportLine site. Please contact Micro Focus Customer Care if you have any queries.

Resolution:

COBOL Server R2 allows applications created with Visual COBOL for Visual Studio 2010/2012/2013 to also be deployed on Windows XP and Windows Server 2003. The R2 installers replace the original installers of COBOL Server and include any fixes delivered with HotFixes 1 to 6 of the COBOL Server 2.2 Update 2 release.

This R2 installer is available for download from the Product Updates page at the MF SupportLine site.

Once the R2 is installed, then you will be able to install HotFix 7 or higher.


Note: Windows XP and Windows Server 2003 support is enabled in conjunction with HotFix 6 or greater for Visual COBOL for Visual Studio, which can be obtained by contacting SupportLine. Please see the Deployment to Windows XP and Windows Server 2003 section within the Release Notes for more information.

Change the external names of my web service's methods and parameters without changing the internal, COBOL, names

$
0
0
Current Revision posted to Visual COBOL Knowledge Base by Steve Jolivet on 10/29/2015 9:38:15 PM
Created On:  22 October 2012

Problem:

By default, Xcentrisity BIS uses the lowercase form of the COBOL names from the --Method-Parameters data group in WORKING-STORAGE in order to generate the external SOAP web service method and parameter names.  However, it is possible to change the default, external, method and parameter without changing the COBOL WORKING-STORAGE names.

Resolution:

In order to define alternate names for web service's methods and parameters you will need to use an XSLT stylesheet, along with an XML conversion dictionary, that convert the original names to the new ones that you wish to implement.  The spelling dictionary is a simple XML document that can be edited by hand.  It contains entries that define the "cobName", internal COBOL data name, and the "publicName", the external SOAP element ,or method, name.

Attached to this Knowledge Base Article is a zip archive containing modified XBIS SOAP stylesheets that enable the use of a dictionary, along with a sample dictionary and a modified webappsample4 program that implements the dictionary through the use of XSLT parameters. The zip archive should be extracted into your Xcentrisity BIS "Samples" virtual directory.

**Be sure to make a backup of the BIS "Samples\Common" directory if you wish to retain the original stylesheets distributed with Xcentrisity BIS.
 
The zip archive contains sytlesheets that need to be located in the BIS "Samples\Common" directory.  The dictionary itself, "testDict.xml", is also included in the "Common" archive directory as it needs to be located in the same directory as the XBIS SOAP transform stylesheets(or you can use the full path to the dictionary in your parameter).  The modified version of webappsample4 that uses the dictionary is located in a directory named, "DictionarySample4".
 
In order to enable the use of the XML dictionary, you need to add the XML dictionary's name as a parameter to your transform.  In the modified webappsample4 source, there is an example of setting the "spellingDictionary" XSLT parameter to define the dictionary document.  For example:
 
           XML SET XSL-PARAMETERS
               "Method_Namespace"     L-Method-Namespace-URI  *> all
               "spellingDictionary"   "testDict.xml".
           If Not XML-OK Go To Z End-If.
    
 

Please contact Micro Focus Customer Care if you have any questions, or, encounter any issues implementing an XML dictionary for your XBIS web service.

Old KB# 36470
Tags: XBIS, COBOL, Dictionary, BIS, Xcentrisity, names

How do I set Visual COBOL Eclipse to remote debug using a specific port?

$
0
0
Current Revision posted to Visual COBOL Knowledge Base by Chris Glazier on 10/30/2015 1:59:32 PM

Below are instructions to enable remote debugging using a specific port:

1) Start the ViewNow X application

2) In Eclipse, choose the dropdown menu named ‘Run’

3) Next, choose ‘Debug Configuration’

4) Fill in the COBOL Project and the Remote Host

5) Check the box for ‘Specify the port on which the cobdebugremote process will listen…’

6) For ‘cobdebugremote port’ enter the port number that you wish to use on the remote Unix system

7) In the box ‘Start Options’ enter (in caps): REMOTERDO

8) Click ‘Apply’ then ‘Run’ buttons

Unable to debug into the Cobol SQL CLR stored procedure

$
0
0
Current Revision posted to Visual COBOL Knowledge Base by evank on 11/5/2015 4:44:51 PM

Problem

When trying to debug into the Cobol SQL CLR stored procedure, you may get the errors below:

1. Get error "Unable to debug .NET code. Could not attach to SQL Server process on xxx".

2. The debugger just steps over the EXEC SQL CALL statement, you cannot step into the stored procedure.

Resolution:

For the first error, you need to run Visual Cobol for Visual Studio as administrator.

For the second issue, please double check the following:

1. The Calling program's project property, debug tab, the Enable SQL Server debugging option is set.

2. In Visual Studio SQL Server Object Explorer, right click the SQL Server instance, and ensure that the Allow SQL/CLR Debugging option is checked.

3. If you have rebuilt the SQL Server Database Project, you need to re-Publish the stored procedure to SQL Server before starting debugging.

Please check Tutorials: SQL Server COBOL Stored Procedures in our documentation for step by step procedure on how to work with Cobol SQL CLR stored procedures.

 

Visual COBOL 2.3 setup fails with MSI error 0x80070643

$
0
0
Current Revision posted to Visual COBOL Knowledge Base by MF_Fano on 11/17/2015 6:30:32 PM

Problem:

Visual COBOL 2.3 for Visual Studio 2015 fails with the following error message:

Setup Failed

0x80070643 - Fatal error during installation.

Fix setup issue(s) and retry. For more information see the log file.

Resolution:

Visual COBOL setup verifies and installs few pre-requisites if missing. When one of these pre-requisites fails to install, then the error above occurs, and the log file should indicate where the problem occurred.

For instance, the error is reported in several lines:

Error 0x80070643: Process returned error: 0x643
Error 0x80070643: Failed to execute EXE package.
Error 0x80070643: Failed to configure per-machine EXE package.
Applied execute package: jre, result: 0x80070643, restart: None
Error 0x80070643: Failed to execute EXE package.

In the fourth line of the error messages above, it indicates that jre was the package that failed.

The actual command is reported in the same log file few or several lines before the error messages with an entry starting with "Applying execute package: <pre-requisite> [...]". In this case, it is jre

Applying execute package: jre, action: Install, path: C:\ProgramData\Package Cache\E0E42AAEEDBB77A19809004A576496DCDCF99ED5\prereqs\jre-8u51-windows-i586.exe, arguments: '"C:\ProgramData\Package Cache\E0E42AAEEDBB77A19809004A576496DCDCF99ED5\prereqs\jre-8u51-windows-i586.exe" /s'

The problem should be resolved by deleting the folder with the long string where the executable is started from, e.g. C:\ProgramData\Package Cache\E0E42AAEEDBB77A19809004A576496DCDCF99ED5\, and by relaunching the Visual COBOL setup.

The alternative, in the case of the Java run-time (jre), would bt to install jre manually by downloading the file from http://www.oracle.com/technetwork/java/javase/downloads/java-archive-javase8-2177648.html

Once the Java runtime is installed, the Visual COBOL 2.3 setup will not need to install it anymore.


Scope of inline usage of IDXFORMAT.

$
0
0
Current Revision posted to Visual COBOL Knowledge Base by tonyt on 11/24/2015 9:48:46 AM

Problem

What happens with IDXFORMAT when combining its usages and using it

  • as a compile time directive.
  • as an inline directive.
  • it inside a file handler configuration file.

Resolution

This is a complex example but hopefully shows how

    the IDXFORMAT directive and

    the external file handler IDXFORMAT option

can be used together.

This examples shows

  • A compile directive IDXFORMAT will override a file handler configuration file IDXFORMAT.
  • An inline directive will affect all index files declared below it in the source file.
  • Other coding techniques like copy with the replace statement and piped file input and output.

OUTPUT from running doit.sh

/home/tonyt/test/2831958idxformat >. ./doit.sh
java version "1.7.0_13"
Java(TM) SE Runtime Environment (build 1.7.0_13-b20)
Java HotSpot(TM) Server VM (build 23.7-b01, mixed mode)
version @(#)cob.c	2.3.0.72
PRN=KXCRH/AAD:Ao.U4.13.04
PTI=32/64 bit
PTI=Micro Focus Visual COBOL Development Hub 2.3
PTI=pkg_106718
PTI=MFInstaller
PTI=ES
PTI=SOA Configured
I see no work (see `cob -?' for help)
/home/tonyt/test/2831958idxformat/data001 does exsist removing files
/home/tonyt/test/2831958idxformat/data002 does exsist removing files
/home/tonyt/test/2831958idxformat/data003 does exsist removing files
/home/tonyt/test/2831958idxformat/data004 does exsist removing files
/home/tonyt/test/2831958idxformat/data005 does exsist removing files
/home/tonyt/test/2831958idxformat/data006 does exsist removing files
/home/tonyt/test/2831958idxformat/data007 does exsist removing files
/home/tonyt/test/2831958idxformat/data008 does exsist removing files
/home/tonyt/test/2831958idxformat/data009 does exsist removing files
version @(#)cob.c	2.3.0.72
PRN=KXCRH/AAD:Ao.U4.13.04
PTI=32/64 bit
PTI=Micro Focus Visual COBOL Development Hub 2.3
PTI=pkg_106718
PTI=MFInstaller
PTI=ES
PTI=SOA Configured
cob64 -C nolist -xcVv -C list() showdir settings=col copyext(cbl,cpy,SL,FD,WS,DS) dg ans85 preprocess(window1) autoclose endp p(cp) endp execjobstepsub1.cbl 
* Micro Focus COBOL                  V2.3 revision 000           Compiler
* Copyright (C) Micro Focus 1984-2015. All rights reserved.
* Accepted - verbose
* Accepted - nolist
* Accepted - list()
* Accepted - showdir
* Accepted - settings(col)
* Accepted - copyext(cbl,cpy,SL,FD,WS,DS)
* Accepted - dg
* Accepted - ans85
* Accepted - preprocess(window1) autoclose
* Accepted - p(cp)
* Compiling execjobstepsub1.cbl
* Total Messages:     0
* Data:        8104     Code:         844
* Micro Focus COBOL Code Generator
* Copyright (C) Micro Focus 1984-2015. All rights reserved.
* Accepted - verbose
* Generating execjobstepsub1
* Data:        7864     Code:        1314     Literals:         128
version @(#)cob.c	2.3.0.72
PRN=KXCRH/AAD:Ao.U4.13.04
PTI=32/64 bit
PTI=Micro Focus Visual COBOL Development Hub 2.3
PTI=pkg_106718
PTI=MFInstaller
PTI=ES
PTI=SOA Configured
cob64 -C nolist -xVv -C list() showdir settings=col copyext(cbl,cpy,SL,FD,WS,DS) dg ans85 idxformat(4) preprocess(window1) autoclose endp p(cp) endp execjobstep.cbl execjobstepsub1.o 
* Micro Focus COBOL                  V2.3 revision 000           Compiler
* Copyright (C) Micro Focus 1984-2015. All rights reserved.
* Accepted - verbose
* Accepted - nolist
* Accepted - list()
* Accepted - showdir
* Accepted - settings(col)
* Accepted - copyext(cbl,cpy,SL,FD,WS,DS)
* Accepted - dg
* Accepted - ans85
* Accepted - idxformat(4)
* Accepted - preprocess(window1) autoclose
* Accepted - p(cp)
* Compiling execjobstep.cbl
* Total Messages:     0
* Data:       18448     Code:        2145
* Micro Focus COBOL Code Generator
* Copyright (C) Micro Focus 1984-2015. All rights reserved.
* Accepted - verbose
* Generating execjobstep
* Data:       18208     Code:        3061     Literals:         320
cob64: Entry points defined in module: execjobstep.o
	*EXECJOBSTEP
	execjobstep
cob64: Entry points defined in module: execjobstepsub1.o
	EXECJOBSTEPSUB1
	execjobstepsub1
execjobstep main Started >>>>
execjobstepsub1 main Started >>>>
<rebuild $dd_idxfile001 -n | grep -E 'Format  |File  '                          
        File                             :   
        Format                           :   IDX-4
                                                  
<rebuild $dd_idxfile002 -n | grep -E 'Format  |File  '                          
        File                             :   
        Format                           :   IDX-4
                                                  
<rebuild $dd_idxfile003 -n | grep -E 'Format  |File  '                          
        File                             :   
        Format                           :   IDX-8
                                                  
<rebuild $dd_idxfile004 -n | grep -E 'Format  |File  '                          
        File                             :   
        Format                           :   IDX-8
                                                  
<rebuild $dd_idxfile005 -n | grep -E 'Format  |File  '                          
        File                             :   
        Format                           :   IDX-3
                                                  
<rebuild $dd_idxfile006 -n | grep -E 'Format  |File  '                          
        File                             :   
        Format                           :   IDX-3
                                                  
<rebuild $dd_idxfile007 -n | grep -E 'Format  |File  '                          
        File                             :   
        Format                           :   IDX-4
                                                  
<rebuild $dd_idxfile008 -n | grep -E 'Format  |File  '                          
        File                             :   
        Format                           :   C-ISAM
                                                   
<recover1 $dd_idxfile009 junk.log -I -Y | grep Index                            
Indexed File Recovery Utility
Indexed File: /home/tonyt/test/2831958idxformat/data009/idxfile009
Number of Index Blocks:          8
Indexed File Recovery Utility
Indexed File: /home/tonyt/test/2831958idxformat/data009/idxfile009
                                                                  
main press any key to return

 

Here is a doit.sh script that will create several files and will show what the IDXFORMAT of the files is set to.

This demo is using Visual COBOL using a UNIX platform.

To download the doit.sh script, click the link and save as < doit.sh > then

Create a test directory.

mkdir testit

Cut and paste doit.sh script into this directory

You need to change the doit.sh to have the location of your Cobol installation.

Then execute the doit.sh script.

. ./doit.sh

doit.sh script

#
java -version
#
COBMODE=64
export COBMODE
# vc setup
#. /home/products/vcdevhub23_pkg106718/bin/cobsetenv
# end vc setup
# sx setup
#COBDIR=/home/products/sx51ws6
#export COBDIR
#
#LD_LIBRARY_PATH=$COBDIR/lib:$LD_LIBRARY_PATH
#export LD_LIBRARY_PATH
#
#PATH=$COBDIR/bin:$PATH
#export PATH
# end sx setup
cob -V
#
# Test IDXFORMAT directive scope
#
# clean up and create required files
export BASE_PWD=$PWD
#
# create data directories or clean them out.
#
for i in {1..9}
do
    export istr=$(printf "%03d" $i)
    if [ ! -d $BASE_PWD/data$istr ]
    then
        echo "$BASE_PWD/data$istr does not exsist creating"
        mkdir $BASE_PWD/data$istr
    else
        echo "$BASE_PWD/data$istr does exsist removing files"
        rm $BASE_PWD/data$istr/*
    fi
    export dd_idxfile$istr=$BASE_PWD/data$istr/idxfile$istr
done
#
# execjobstep.cbl is compiled with idxformat it will overide the EXTFH file
# execjobstepsub1.cbl is called by execjobstep.cbl and does not use idxformat
# so should use the contents of the EXTFH file below.
#
cat >myextfh.cfg <<EOF
[XFH-DEFAULT]
IDXFORMAT=1
INDEXCOUNT=32
STRIPSPACE=OFF
RUNITLOCKDETECT=OFF
[FOLDER:$BASE_PWD/data007]
IDXFORMAT=4
[FOLDER:$BASE_PWD/data009]
IDXFORMAT=21

EOF
#
export EXTFH=$BASE_PWD/myextfh.cfg
#
# lets create the source files
#
cat >execjobstep.cbl <<EOF
       identification division.
       program-id. execjobstep.
      *
      * Test IDXFORMAT directive scope 
      *
       environment division.
       configuration section.
       input-output section.
       file-control.
       
           select inputpipe 
               assign to disk ws-inputpipe
               organization is line sequential
               file status is file-status.

       copy "idxfile.SL" replacing =="(idxfile)"== by 
                                   =="idxfile001"==
                                   ==(idxfile)== by
                                   ==idxfile001==.

       copy "idxfile.SL" replacing =="(idxfile)"== by 
                                   =="idxfile002"==
                                   ==(idxfile)== by
                                   ==idxfile002==.

      \$set idxformat"8"
       copy "idxfile.SL" replacing =="(idxfile)"== by 
                                   =="idxfile003"==
                                   ==(idxfile)== by
                                   ==idxfile003==.

       copy "idxfile.SL" replacing =="(idxfile)"== by 
                                   =="idxfile004"==
                                   ==(idxfile)== by
                                   ==idxfile004==.

      \$set idxformat"3"
       copy "idxfile.SL" replacing =="(idxfile)"== by 
                                   =="idxfile005"==
                                   ==(idxfile)== by
                                   ==idxfile005==.

       copy "idxfile.SL" replacing =="(idxfile)"== by 
                                   =="idxfile006"==
                                   ==(idxfile)== by
                                   ==idxfile006==.

       data division.
       file section.

       fd  inputpipe
           record varying from 1 to 1024 characters 
               depending on inputpipe-line-length.
       01  inputpipe-rec                         pic x(1024).

       copy "idxfile.FD" replacing ==(idxfile)== by 
                                   ==idxfile001==.

       copy "idxfile.FD" replacing ==(idxfile)== by 
                                   ==idxfile002==.

       copy "idxfile.FD" replacing ==(idxfile)== by 
                                   ==idxfile003==.

       copy "idxfile.FD" replacing ==(idxfile)== by 
                                   ==idxfile004==.

       copy "idxfile.FD" replacing ==(idxfile)== by 
                                   ==idxfile005==.

       copy "idxfile.FD" replacing ==(idxfile)== by 
                                   ==idxfile006==.

       working-storage section.
       01  inputpipe-line-length                 pic 9(4).      
       copy "idxfile.WS" replacing ==(idxfile)== by 
                                   ==ws-idxfile001==
                                   ==(idxfilelength)== by
                                   ==idxfile001==.

       copy "idxfile.WS" replacing ==(idxfile)== by 
                                   ==ws-idxfile002==
                                   ==(idxfilelength)== by
                                   ==idxfile002==.

       copy "idxfile.WS" replacing ==(idxfile)== by 
                                   ==ws-idxfile003==
                                   ==(idxfilelength)== by
                                   ==idxfile003==.

       copy "idxfile.WS" replacing ==(idxfile)== by 
                                   ==ws-idxfile004==
                                   ==(idxfilelength)== by
                                   ==idxfile004==.

       copy "idxfile.WS" replacing ==(idxfile)== by 
                                   ==ws-idxfile005==
                                   ==(idxfilelength)== by
                                   ==idxfile005==.

       copy "idxfile.WS" replacing ==(idxfile)== by 
                                   ==ws-idxfile006==
                                   ==(idxfilelength)== by
                                   ==idxfile006==.

       01  ans                                   pic x.
       
       01  file-status.
           03  status-key-1                      pic x.
           03  status-key-2                      pic x.

       01  abort-flag                            pic x value "N".
           88  not-in-abort                        value "N".
           88  in-abort                            value "Y".

       01  ws-inputpipe                          pic x(1024) 
                                                   value spaces.
       
       01  i                                     pic 999.

       procedure division.
       declaratives.

       copy "idxfile.DS" replacing =="(idxfile)"== by 
                                   =="idxfile001"==
                                   ==(idxfile)== by
                                   ==idxfile001==.

       copy "idxfile.DS" replacing =="(idxfile)"== by 
                                   =="idxfile002"==
                                   ==(idxfile)== by
                                   ==idxfile002==.

       copy "idxfile.DS" replacing =="(idxfile)"== by 
                                   =="idxfile003"==
                                   ==(idxfile)== by
                                   ==idxfile003==.

       copy "idxfile.DS" replacing =="(idxfile)"== by 
                                   =="idxfile004"==
                                   ==(idxfile)== by
                                   ==idxfile004==.

       copy "idxfile.DS" replacing =="(idxfile)"== by 
                                   =="idxfile005"==
                                   ==(idxfile)== by
                                   ==idxfile005==.

       copy "idxfile.DS" replacing =="(idxfile)"== by 
                                   =="idxfile006"==
                                   ==(idxfile)== by
                                   ==idxfile006==.

       copy "common.DS".

       end declaratives.

       main section.
       main-010.
           display "execjobstep main Started >>>>"
           set not-in-abort to true

           open output idxfile001,
                       idxfile002,
                       idxfile003,
                       idxfile004,
                       idxfile005,
                       idxfile006
           close idxfile001,
                 idxfile002,
                 idxfile003,
                 idxfile004,
                 idxfile005,
                 idxfile006

           call "execjobstepsub1"

           perform varying 
               i from 1 by 1
               until i > 9
               if i = 9
      *  RM file number 9 see EXTFH file above
      *  so use the recover1 utility    
                   move spaces to ws-inputpipe
                   string "<recover1 \$dd_idxfile", 
                           i,
                           " junk.log -I -Y | grep Index"
                   into ws-inputpipe
               else
                   string "<rebuild \$dd_idxfile", 
                           i,
                           " -n | grep -E 'Format  |File  '"
                   into ws-inputpipe
               end-if
               display ws-inputpipe(1:80)
               perform idxformat-disp
           end-perform
           
           display "main press any key to return"
           accept ans
           .
       main-090.
           goback.

       idxformat-disp section.
       idxformat-disp-010.
           open input inputpipe
           read inputpipe
           display inputpipe-rec(1:inputpipe-line-length)
           perform until file-status <> "00"
               read inputpipe
               display inputpipe-rec(1:inputpipe-line-length)
           end-perform
           close inputpipe
           .
       idxformat-disp-090.
           exit.

       end program execjobstep.

EOF
#
# create a sub module not using IDXFORMAT
# so this will use the EXTFH file defined above
#
cat >execjobstepsub1.cbl <<EOF
       identification division.
       program-id. execjobstepsub1.
      *
      * Test EXTFH 
      *
       environment division.
       configuration section.
       input-output section.
       file-control.
       
       copy "idxfile.SL" replacing =="(idxfile)"== by 
                                   =="idxfile007"==
                                   ==(idxfile)== by
                                   ==idxfile007==.

       copy "idxfile.SL" replacing =="(idxfile)"== by 
                                   =="idxfile008"==
                                   ==(idxfile)== by
                                   ==idxfile008==.

       copy "idxfile.SL" replacing =="(idxfile)"== by 
                                   =="idxfile009"==
                                   ==(idxfile)== by
                                   ==idxfile009==.

       data division.
       file section.

       copy "idxfile.FD" replacing ==(idxfile)== by 
                                   ==idxfile007==.

      * using c-isam cant do varying record length, see idxfile.FD 
       fd  idxfile008.
       01  idxfile008-rec.
           03  idxfile008-primary-key.
               05  idxfile008-sequence           pic 9(9).
               05  idxfile008-suffix             pic 9.
           03  filler                            pic x(1014).

       copy "idxfile.FD" replacing ==(idxfile)== by 
                                   ==idxfile009==.

       working-storage section.
       copy "idxfile.WS" replacing ==(idxfile)== by 
                                   ==ws-idxfile007==
                                   ==(idxfilelength)== by
                                   ==idxfile007==.

       copy "idxfile.WS" replacing ==(idxfile)== by 
                                   ==ws-idxfile008==
                                   ==(idxfilelength)== by
                                   ==idxfile008==.

       copy "idxfile.WS" replacing ==(idxfile)== by 
                                   ==ws-idxfile009==
                                   ==(idxfilelength)== by
                                   ==idxfile009==.

       01  file-status.
           03  status-key-1                      pic x.
           03  status-key-2                      pic x.

       01  abort-flag                            pic x value "N".
           88  not-in-abort                        value "N".
           88  in-abort                            value "Y".

       procedure division.
       declaratives.

       copy "idxfile.DS" replacing =="(idxfile)"== by 
                                   =="idxfile007"==
                                   ==(idxfile)== by
                                   ==idxfile007==.

       copy "idxfile.DS" replacing =="(idxfile)"== by 
                                   =="idxfile008"==
                                   ==(idxfile)== by
                                   ==idxfile008==.

       copy "idxfile.DS" replacing =="(idxfile)"== by 
                                   =="idxfile009"==
                                   ==(idxfile)== by
                                   ==idxfile009==.

       copy "common.DS".

       end declaratives.

       main section.
       main-010.
           display "execjobstepsub1 main Started >>>>"
           set not-in-abort to true

           open output idxfile007,
                       idxfile008,
                       idxfile009
           close idxfile007,
                 idxfile008,
                 idxfile009
           .
       main-090.
           goback.

       end program execjobstepsub1.

EOF
#
cat >idxfile.WS <<EOF
       01  (idxfilelength)-line-length           pic 9(4).
        
       01  (idxfile)-rec.
           03  (idxfile)-primary-key.
               05  (idxfile)-sequence            pic 9(9).
               05  (idxfile)-suffix              pic 9.
           03  filler                            pic x(1014).

EOF
#
cat >idxfile.SL <<EOF
           select optional (idxfile) 
      *      select (idxfile)
               assign to disk "(idxfile)"
               organization is indexed
               access is dynamic
               record key is (idxfile)-primary-key
               file status is file-status.

EOF
#
cat >idxfile.FD <<EOF
       fd  (idxfile)
           record varying from 10 to 1024 characters 
               depending on (idxfile)-line-length.
       01  (idxfile)-rec.
           03  (idxfile)-primary-key.
               05  (idxfile)-sequence            pic 9(9).
               05  (idxfile)-suffix              pic 9.
           03  filler                            pic x(1014).

EOF
#
cat >idxfile.DS <<EOF
       decl(idxfile) section.
           use after standard error procedure on (idxfile).
       decl(idxfile)-010.
           display "decl", "(idxfile)", " declarative executing"
           perform check-file-status
           .
       decl(idxfile)-090.
           exit.

EOF
#
cat >common.DS <<EOF
       check-file-status.
           display "check-file-status file-status <",
                                      file-status, ">"
           set in-abort to true
           .

EOF
#
# compile the source files, just put some preprocessors here to show usage
#
cob -xcVv -C "list() showdir settings=col copyext(cbl,cpy,SL,FD,WS,DS) dg ans85 preprocess(window1) autoclose endp p(cp) endp" execjobstepsub1.cbl
#
cob -xVv -C "list() showdir settings=col copyext(cbl,cpy,SL,FD,WS,DS) dg ans85 idxformat(4) preprocess(window1) autoclose endp p(cp) endp" execjobstep.cbl execjobstepsub1.o
#
# lets run the test
#
./execjobstep
#
# end
#

 

Look at the listings after running to see the copy book statements working with the replace statements.

Look at the EXTFH config file, to see how to make the C-ISAM file the default, as some old systems use this.

Tags: visual cobol, IDXFORMAT, COBOL, extfh, UNIX

UNIX terminal escape sequences.

$
0
0
Current Revision posted to Visual COBOL Knowledge Base by tonyt on 11/24/2015 10:40:19 AM

Problem

The terminal emulation software escape key sequence does not match the UNIX TERMINFO escape sequence.

How do you identify the escape key sequence to use in a TERMINFO file for a particular key depression like F2 or shift + F2 etc…

Resolution

Here is a program scanwinput.c to display the escape sequences received by a UNIX system, which can be used to update your TERMINFO files.

Getting this output is a good step to solving the complex issue of terminal configuration on UNIX platforms.

OUTPUT from program when pressing F2 key

lines <25> columns <70> termname

longname xterm terminal emulator (X Window System)

 

  

Enter a string or key sequence like ctrl-f4 to see hex values or q exit

<^[OQ                                                              >

You Entered       : ^[OQ

You entered in hex : 1b4f51

Press any key to continue :

 

scanwinput.c will show all available options for the TERMINFO file in use.

OUTPUT scanwinput.c option d

str ked           key_eos                      = ABSENT_STRING

str kf0             key_f0                         = ABSENT_STRING

str kf1             key_f1                         = \EOP

str kf10           key_f10                      = \E[21~

str kf2             key_f2                         = \EOQ

str kf3            key_f3                         = \EOR

 

The above shows that kf2 is ”\E” escape x’1b’ and “OQ” which is what we got when we pressed the F2 key so good match.

We can expand a mftic generated TERMINFO file using mfinfocmp to see the TERMINFO source

OUTPUT mfinfocmp

mfinfocmp -1 | grep kf2=

               kf2=\EOQ,

  

Change the output from mfinfocmp and put it back in the TERMINFO database using mftic.

 The c source code

To download the c source code, click the link and save as < scanwinput.c >

scanwinput.c

/* to see what ncurses can do see */
/* http://www.tldp.org/HOWTO/NCURSES-Programming-HOWTO/index.html */
/* http://frank.harvard.edu/~coldwell/ncurses/ncurses-intro.html this one looks good first has examples */
/* now this is the mecca of ncurses sites the curses test site */
/* http://stuff.mit.edu/afs/sipb/project/ncurses/cron-working/ncurses/test/ */

#include <stdio.h>
#if defined(_AIX)
#include <curses.h>
#define ABSENT_BOOLEAN         ((signed char)-1)       /* 255 */
#define ABSENT_NUMERIC         (-1)
#define ABSENT_STRING          (char *)0
#define CANCELLED_STRING	     (char *)(-1)
#else
#include <ncurses/ncurses.h>
#include <ncurses/term.h>
#include <ncurses/tic.h>
#endif

#include <string.h>
#include <stdbool.h>
#include <ctype.h>

#define STR1LEN 15
#define STR2LEN 30
#define FCAPDISP(type, str1, str2) "%s %-*s %-*s = ", #type, STR1LEN, str1, STR2LEN, str2

int main() {

	WINDOW *_window = initscr();

	char mesg[] =
			"Enter a string or key sequnce like ctrl-f4 to see hex values or q exit"; /* message to be appeared on the screen */
	char mesg1[] =
			"<                                                                    >"; /* place to get string data escape sequences */
	char str[strlen(mesg1) - 2];
	int row, col; /* to store the number of rows and */
	/* the number of colums of the screen */
	getmaxyx(_window, row, col); /* get the number of rows and columns */

	do {
#if defined(_AIX)
    mvprintw(row/4,(col-strlen(mesg))/2, 
        "lines <%s> columns <%s> termname <%s>", termdef(2, 'l'), termdef(2, 'c'), termdef(2, 't'));
#else
    mvprintw(row / 4, (col - strlen(mesg)) / 2,
        "lines <%d> columns <%d> termname <%s>", row, col, termname());
#endif
		mvprintw((row / 4) + 1, (col - strlen(mesg)) / 2, "longname %s",
				longname());

		mvprintw(row / 2, (col - strlen(mesg)) / 2, "%s", mesg); /* print the message at the center of the screen */
		mvprintw(row / 2 + 1, (col - strlen(mesg)) / 2, "%s", mesg1);
		move(row / 2 + 1, ((col - strlen(mesg)) / 2) + 1);
		refresh();

		getstr(str);
		if (str[0] == 'q')
			break;
		mvprintw(row / 2 + 2, (col - strlen(mesg)) / 2,
				"You Entered        : %s", str);
		mvprintw(row / 2 + 3, (col - strlen(mesg)) / 2,
				"You entered in hex : ");
		int n;
		for (n = 0; str[ n ] != '\0'; n++)
			printw("%02x", (unsigned char) str[ n ]);
		mvprintw(row / 2 + 4, (col - strlen(mesg)) / 2,
				"Press any key to continue : ");
		refresh();
		getch();
		clear();
	} while (true);

	mvprintw(row - 2, 0, "Press any key to exit d to see terminfo : ");
	refresh();
	char c = getch();
	endwin();

	/* using stuff from mecca site above dump terminfo stuff */
	if (c == 'd') {
		printf("mftic and mfinfocmp must be used for TERMINFOS being used by MF COBOL\n");
		printf("mftic puts key definitions in different places than tic so must use mftic\n");
		printf("mftic uses old ncurses libraries so definitions need to be compiled and extracted\n");
    printf("using mftic and mfinfocomp, enough said.\n");
		printf("\n");
#if defined(_AIX)
    printf("%s|%s\n", termdef(2, 't'), longname()); 
#else
		printf("%s|%s\n", termname(), longname());
#endif
		fflush(stdout);
		unsigned n;
		char *cap;
		char *capf;
		const char *str;
		int num;

		for (n = 0;; ++n) {
			cap = boolnames[ n ];
			capf = boolfnames[ n ];
			if (cap == 0)
				break;
			num = tigetflag(cap);
			printf(FCAPDISP(flg, cap, capf));
			if (num == ABSENT_BOOLEAN) {
				printf(" ABSENT_BOOLEAN\n");
			} else {
			    printf(" %s\n", num ? "true" : "false");
			}
			fflush(stdout);
		}

		for (n = 0;; ++n) {
			cap = numnames[ n ];
			capf = numfnames[ n ];
			if (cap == 0)
				break;
			printf(FCAPDISP(num, cap, capf));
			num = tigetnum(cap);
			if (num == ABSENT_NUMERIC) {
				printf(" ABSENT_NUMERIC\n");
			} else {
				printf(" %d\n", num);
			}
			fflush(stdout);
		}

		for (n = 0;; ++n) {
			cap = strnames[ n ];
			capf = strfnames[ n ];
			if (cap == 0)
				break;
			printf(FCAPDISP(str, cap, capf));
			str = tigetstr(cap);
			if (str == CANCELLED_STRING) {
				str = "CANCELLED_STRING";
			} else if (str == ABSENT_STRING) {
				str = "ABSENT_STRING";
			}
			while (*str != 0) {
				int ch = (int) *str++;
				switch (ch) {
				case '\177':
					fputs("^?", stdout);
					break;
				case '\033':
					fputs("\\E", stdout);
					break;
				case '\b':
					fputs("\\b", stdout);
					break;
				case '\f':
					fputs("\\f", stdout);
					break;
				case '\n':
					fputs("\\n", stdout);
					break;
				case '\r':
					fputs("\\r", stdout);
					break;
				case ' ':
					fputs("\\s", stdout);
					break;
				case '\t':
					fputs("\\t", stdout);
					break;
				case '^':
					fputs("\\^", stdout);
					break;
				case ':':
					fputs("\\072", stdout);
					break;
				case '\\':
					fputs("\\\\", stdout);
					break;
				default:
					if (isgraph(ch))
						fputc(ch, stdout);
					else if (ch < 32)
						printf("^%c", ch + '@');
					else
						printf("\\%03o", ch);
					break;
				}
			}
			printf("\n");
			fflush(stdout);
		}

	}

	return 0;
}

 

To compile on UNIX

cob -xv scanwinput.c -lcurses -o scanwinput

 

This is just a starting point for solving TERMINFO problems.

Tags: UNIX TERMINFO C ESCAPE-SEQUENCE TERMINAL, COBOL

No terminal output using call "system" in JVM COBOL

$
0
0
Current Revision posted to Visual COBOL Knowledge Base by PhillR on 11/30/2015 11:51:06 PM

Problem

When using call "system" to start a a new process from a JVM COBOL program, ACCEPT and DISPLAY statements in the new process do not work.

Resolution

The JVM runtime uses the underlying support in Java’s Process class which is written to be portable etc.  This has the side effect than on Unix/Linux the support it has no notion of terminal I/O.

So, this means that you can’t use CALL “system” in JVM where the new process is doing terminal i/o.  However there is a work-around.  You can use xterm –e to start a new X-term window and run a script.  For example, here is a demo where test1.cbl calls a script, runs2.sh.  The script set-ups the environment needed for cobjrun.  This is required due to a Unix/Linux security feature which prevents spawned processes from inheriting the LD_LIBRARY_PATH.

For the demo both test1.cbl and test2.cbl were compiled with cob –j.  To run use cobjrun test1.


test1.cbl:

        01  ws-runit-id pic x(8) comp-5.
        01  ws-stack    pic x(4) comp-5.
        01  ws-flags    pic x(4) comp-5 value 1.
        01  ws-status   pic x(4) comp-5.

        procedure division.

        display "in test 1"

        call "system" using z"xterm -e /runs2.sh"

        display "back in test 1"
        goback.


runs2.sh:

export LD_LIBRARY_PATH=$COBDIR/lib:$LD_LIBRARY_PATH
cobjrun test2


test2.cbl:

        01 ws-key pic x.

        procedure division.

        display "in test 2 - press a key"
        accept ws-key
        display "you pressed " ws-key
        goback.

NOTE – The DISPLAY environment variable needs to be set to an X-Windows server.  If running a terminal emulator from Windows you will require an X-Windows server running on the PC to allow the new window to be created on the PC’s screen.

When you run the demo, test1 uses the main terminal window.  When the runs2.sh script is run a new window is created and all accept and display i-o in test2.cbl goes to the new window.  When test2 terminates, the window is destroyed and test1 continues in the original terminal window.

The xterm command takes lots of parameters which allow you to configure the look and feel of the new window.

Tags: call "system" JVM

Inserting PIC N data into an NCHAR column results in incorrect data held in the database.

$
0
0
Current Revision posted to Visual COBOL Knowledge Base by PhillR on 11/30/2015 11:51:53 PM

Problem

Using COBSQL to pre-compile an Oracle SQL program which inserts PIC N data into a column defined as NCHAR  results in incorrect data held in the database.

Resolution


For PIC N variables and NCHAR columns you need to set the Oracle NLS_NCHAR environment variable to match the NLS_NCHAR_CHARACTERSET for the database.

So assuming a UTF-16 setting for the database of NLS_NCHAR_CHARACTERSET=AL16UTF16, set NLS_NCHAR=AL16UTF16 on the client.

Then recompile using only default Pro*COBOL directives and the NSYMBOL(NATIONAL) Micro Focus compiler directive.  Running the test program (see below), resulted in the following inserted in the COL1 column when running on Linux:

"346C200020002000200020002000200020002000"

As you can see, the byte ordering appears to be reversed.  This can be changed if needed using UNICODE(PORTABLE) instead of the default UNICODE(NATIVE) directive, which gives:

"6C34002000200020002000200020002000200020"

In the above string you have 1 unicode character U+6C34 followed by 9 spaces (U+0020).


Demo program:

      $SET NSYMBOL(NATIONAL)
      $SET UNICODE(PORTABLE)
      $SET P(COBSQL) END-C CHARSET_PICN=NCHAR_CHARSET ENDP
      
       IDENTIFICATION DIVISION.
       PROGRAM-ID.    TESTN.

       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.

       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
           exec sql begin declare section end-exec.
       01 ws-char pic x(40).
       01  N1                          PIC  N(10).
       77  DB-STRING                   PIC  X(10)  VALUE "orcl1g".
       77  USERNAME                    PIC  X(10)  VALUE "scott".
       77  PASSWD                      PIC  X(20)  VALUE "tiger".
           exec sql end declare section end-exec.

           EXEC SQL INCLUDE SQLCA    END-EXEC.

       PROCEDURE DIVISION.
           MOVE NX'6C34'               TO N1.
           DISPLAY N1.

           EXEC SQL CONNECT :USERNAME IDENTIFIED BY :PASSWD
                    USING :DB-STRING
           END-EXEC.
           DISPLAY "connect sqlcode: " SQLCODE.
      *
           exec sql
             CREATE TABLE TESTNCHAR
             (COL1 NCHAR(10) DEFAULT(' ') NOT NULL)
           end-exec.

           display "create sqlcode: " sqlcode

           EXEC SQL
               INSERT INTO TESTNCHAR
                      ( COL1 )
               VALUES ( :N1 )
           END-EXEC.

           DISPLAY "insert sqlcode: " SQLCODE.

           exec sql
               select rawtohex(COL1)
               into :ws-char
               from TESTNCHAR
           end-exec.
           display "select sqlcode: " sqlcode " data: " ws-char

           exec sql drop table TESTNCHAR end-exec.
      *
           EXEC SQL COMMIT
           END-EXEC.
      *
           STOP RUN.

Tags: COBSQL Oracle NCHAR NLS_LANG NLS_NCHAR

Localization in Visual COBOL

$
0
0
Revision 1 posted to Visual COBOL Knowledge Base by RickM on 12/3/2015 3:25:34 PM

Prelude

Several examples of how to utilize COBOL in a Microsoft .NET environment have been circulating for a number of years. Some of these examples are quite dated and due to Framework enhancements, (2.0, 3.0, 4.0, 4.5 and now 4.6) the use of the namespaces as well as the syntax used to access them has changed significantly. Micro Focus recently released Visual COBOL 2.3, our flag-ship product for Visual Studio 2015. With a number of changes that have occurred in both .NET and Visual COBOL an update of all our previous articles is in order. So over the next couple of months we will be updating all of our previous articles to the latest versions and introducing new articles with new content. We hope you find these articles educational and valuable to you and a benefit to your organization.

Overview Do you create applications for use in multiple locations and languages? This article will show you how to use the power of LOCALIZATION within Visual Studio .NET to create one screen and have it display different languages. The source code was created with Microsoft Visual Studio.NET 2015 and Micro Focus Visual COBOL 2.3 HF1.

Background

With many companies being multi-national, developers are having to create applications not only in their native language, but also in languages for the countries in which their company has offices. Many times these additional languages present unique challenges due to the presence of local variants to the base language. In the past developers created the application in their language and copied the application to a new name and changed the presentation to the language where the application was going to be deployed. This resulted in having the same program exist for different languages, same core logic, but different presentation layer.

Through the use LOCALIZATION in Visual Studio.NET you can now create one code-base and have multiple presentation layers in different languages use the same code-base. Our example will use a simple WinForm that will enable you to view a screen in either English or German. Please remember though, the intent of the article is to show you how to enable multiple languages, and not present you with a completed application.

Our application has two screens. An Introductory screen:


 

and a presentation screen:

 

It is the presentation screen we will enhance to display in German. We will not go into the specifics how to create a WinForm application using Visual COBOL. Please refer to the online documentation for assistance.

Multi-Language Capabilities

Microsoft has enabled multi-language capabilities within Visual Studio.NET via a combination of the LOCALIZABLE and LANGUAGE settings for the Form you are working on. By default, your language setting is set to the local area where you are. By changing these variables, you can create language targeted screens.

Within Visual Studio.NET 2015 there are two ways to create a foreign language representation of your screens. One way is to use the utility "WINRES" and the other is to use the Designer. I chose to use the Designer so I can visually see what the changes will be to my screen and if any additional enhancements to the form will be required by changing the text being displayed. You begin by selecting your Form and reviewing the properties, looking under the “Design” area for the LOCALIZABLE and LANGUAGE settings as such:

Notice the LANGUAGE and LOCALIZABLE settings are set to English(United States) and True respectively.  This isn’t the default behavior. When you create a new form the settings are ‘Default’ and ‘False’ respectively. Make sure to set these two properties to enable localization but also to set your ‘home’ language. I want to create a form in German so we need to change the LANGUAGE to Germany (Germany) by using the drop-down list. Notice the different versions of German available to you? You can target the specific dialect of a language by first reviewing the options available to you and then selecting the closest version of that language.

For further information on what language settings are available see the CultureInfo Class in the .NET Framework help.

 When you select a new language you will notice the creation of several new files in the Solution Explorer. These files are XML based project files that will contain the language specific items for the screen.  The following image shows the files:

If you were to look at these files in VS.NET you will see they appear as spreadsheets with the name, value and other pieces of information necessary for VS.NET to display the new values. Take a moment and review the files in the solution provided. You will see the values for the labels already present.

The ’Demo.resx’ file is the original file with all the controls and some properties associated with each of the controls. If you look towards the bottom of the file you will see the Labels we created along with the ‘Text’ property for each label and its current value.

In order to present a screen in German we need to update the Text property for all our labels in this file. The simplest way to do this is to ‘split screen’ your work area and have the existing ‘Demo.resx’ file on one side, and the ‘Demo-de-DE.resx’ on the other. Then it’s a simple matter of either copying/pasting each cell from one side to the other, or re-keying the information with the new values for German for the ‘Value’.

The Driver Program

Since I do not want to change the code page my computer is using I created the driver program to demonstrate the use of the multi-language capabilities. The driver program, FORM1.COB, has two methods (one for each click event of the command buttons) that set a variable, create a new Globalization instantiation and finally show the form using the new Globalization instance.

LangDemo was established in the Class level Working-Storeage Section as a reference to the DEMO form. We also defined a flag (ws-lang-ind) to tell us what language we are going to be displaying.

We instantiate the form, passing it a flag telling it which language we want to use and then show the form. The real secret is in the "NEW"  method of the DEMO class.

Enablement

An overloaded "NEW" method was created in the DEMO program.


The original "NEW" method is shown for comparison. Two variables were added, an object reference to the CULTUREINFO class (objGlobalization) and a LINKAGE parameter to accept the value being passed from the driver program (lang-ind).

The language indicator being passed in is evaluated. The values used for the instantiation of the CultureInfo class were determined from the documentation and from the value created for the RESX files. The properties for the CURRENTCULTURE and CURRENTUICULTURE must be set to the new culture info we established prior to invoking the InitializeComponent method. When the form is displayed, depending on which language was selected will determine which form is displayed. Windows will now display the proper information for the correct language.

With the release of Visual COBOL 2.3 the syntax utilized within Visual Studio and relating to .NET has been updated to reflect more of the way C# developers are used to seeing method and parameter definitions. The following example shows the same ‘NEW’ method updated to reflect the changes in Visual COBOL 2.3:

If you’ll notice, the Linkage Section has been removed along with the variable declaration for the language indicator, lang-ind. Instead the language indicator has been defined in the method header and is defined using the standard .NET data type of character. The overall appearance now is more in-line with what a C# developer would be used to seeing. Both examples of the ‘NEW’ method are included in the sample provided. Take some time and review the versions and see which way works for you.

English

German

Wrap-Up

That's it! Once you see how it is done the process is so simple, yet very, very efficient and effective! Unzip the source file, rebuild the solution and execute the process without debugging the first time so you see what is displayed. Next step into the code and visually see what is occurring. Finally, and this should put everything into perspective for you, select the English language in the LANGUAGE property, then select a new language, say Italian. Notice the files that are created and then modify the screen in the Designer to say 'Italian' instead of 'German'. Then add a button to the driver program to call your new Italian screen. Finally update the overloaded "NEW" method to create an Italian instantiation of the CultureInfo class, recompile the solution and see what happens.

Maintenance Note: Once you have created the new screens you can provide a translator or someone familiar with the local language, the spreadsheet representation of your screen and they can 'tweak and tune' the language to be more accurate. You can then maintain the specific language items in the spreadsheet.

I hope you find this article interesting and useful! Happy Coding!

 

Tags: visual cobol, COBOL, .net localization, .net regional, .net local, .net COBOL XML managed

Accessing COBOL Data Groups

$
0
0
Current Revision posted to Visual COBOL Knowledge Base by RickM on 12/21/2015 4:15:17 PM

Prelude

Several examples of how to utilize COBOL in a Microsoft .NET environment have been circulating for a number of years. Some of these examples are quite dated and due to Framework enhancements, (2.0, 3.0, 4.0, 4.5 and now 4.6) the use of the namespaces as well as the syntax used to access them has changed significantly. Micro Focus recently released Visual COBOL 2.3, our flag-ship product for Visual Studio 2015. With a number of changes that have occurred in both .NET and Visual COBOL an update of all our previous articles is in order. So over the next couple of months we will be updating all of our previous articles to the latest versions and introducing new articles with new content. We hope you find these articles educational and valuable to you and a benefit to your organization.

 

This particular article has benefited from a number of changes in Micro Focus Visual COBOL. The addition of interfacing capabilities in .NET and JVM have made the process of accessing data hidden in COBOL applications much simpler for not only the C# developer but also for the COBOL developer who has to provide the access to the data stores. Spend a few minutes reviewing the article and see how simply you can now access COBOL based data from C# or VB.NET or Java or any other distributed language.

Article Description 

COBOL programmers have for years used '01' level (or Group Descriptions) as a means of creating a data structure for related items. It would be safe to say these Data Groups are used in just about every COBOL program that has been written and probably will ever be written. They provide a quick way for COBOL programmers to group together data that has some form of relationship. For example, the name of a region and the total sales for a particular timeframe as in the following structure:

In the above sample we see an '01' (or Group) description for a field called WS-Branch-Rec. This is the highest definition for a related group of data items. Underneath this item there are two additional data items, WS-BRANCH-NAME and WS-BRANCH-TOT. Each of these items occurs 10 times in a table. You can think of the structure in terms of a spreadsheet, 10 rows with two columns of data. The variable WS-BRANCH-NAME is defined as a "PIC X(50)" which means it is 50 characters in length and is an alphanumeric data item (or a String in C#). WS-BRANCH-TOT is defined as a "PIC 9(12)" is a numeric data item. The equivalent in C# would be an integer.

In this article we will begin with a C# console application calling a COBOL DLL file. The C# application will pass it a number of occurrences to create a table (much like a user requesting a specific number of months to report on). The COBOL program will accept the user request (which we have currently defaulted to 5), create the data group and pass control back to the C# program. The C# program will then read in the data group and display the results on the screen.

Please keep in mind that while the example is not of a completely finished and polished application the intent is to demonstrate how to utilize your existing COBOL business logic and interact with a new C# front-end.

C# coding

We will assume you are comfortable with the C# language. If you have any questions in this area please consult with one of your local C# experts.

As we mentioned above, we will call the COBOL program, passing it a variable to define the number of occurrences we wish to populate. The following code illustrates how to do this:



The first three lines are basic display statements to inform the operator we are beginning the process. The fourth line of code though instantiates our COBOL program. The fifth line of code is the key to working with the COBOL data groups. In this line we create an instance of the data that we have defined in our COBOL program. This data has been exposed using a compiler directive added when the COBOL program was built within Visual Studio.

In the Properties for the COBOL program we added two new compiler directives: ilsmartlinkage and ilcutprefix(WS-) as shown:



The two compiler directives:

 

Directive

Description

ilsmartlinkage

Exposes the linkage section and entry points to managed code by creating types

ilcutprefix()

Removes a specified prefix from the names of the COBOL data items in the source code

 

The COBOL program has had no changes made to it. It was simply recompiled with the above two directives to expose the linkage section for use by other languages.



The PERFORM loop creates the number of occurrences in the table based on the input parameter CTR. This parameter was passed to it by the C# class. This is standard COBOL and we will not delve into an explanation of this code other than to mention this could be your existing COBOL program(s). They would continue to operate and perform the tasks for which they were designed.

Returning to the C# program


 

Upon our return to the C# program we need to retrieve the data. The following code accomplishes this and displays it to the console window:

We have created a 'for loop' to process the correct number of times according to our previously defined counter (Ctr). Again, one note, the .NET Framework operates as zero based, not one based so we need to begin our array index at zero. This implies then that our ending number will be one less than the count the COBOL system utilized, or 4 in our case. The 'for loop' has been created to begin at zero, determine if "ctr" is less than or equal to 4 and then increment the counter if it is.

Within the 'for loop' the first line of code retrieves the amount using a ‘get’ method for the data item which was created as part of the compilation process by the COBOL compiler. A similar statement is executed for the ‘name’ data element and written out to the console. When processing has completed a ‘readline’ is executed so you can see the data before the window closes.


 

Wrap-Up

 DataGroups.zip

The ZIP file has all the necessary source code for you to follow along and see how the code is to be structured. Being able to utilize an existing COBOL data structure in the .NET Framework will greatly expand the interoperability and life of your existing COBOL applications but also provide .NET Developers a way to access data that is much simpler and straightforward. While the process may seem complicated at first, spend a few minutes and analyze what we've done in this article. The steps will be basically the same for you and will greatly extend the usefulness of your existing applications to the .NET Framework. And that's what it's all about...

Happy Coding!


Update:

An Eclipse version of the Data Groups project is attached as well. The same principles apply showing how Java can interact with COBOL data.

EclipseDataGrps.zip

 

Tags: visual cobol, COBOL, C#, data. Java, data exchange, JVM

Working with the DateTimePicker in Micro Focus Visual COBOL for .NET

$
0
0
Current Revision posted to Visual COBOL Knowledge Base by RickM on 1/6/2016 5:00:27 PM

Working with the DateTimePicker in Micro Focus Visual COBOL for .NET

One of the most frequent tasks a COBOL developer has to perform is date manipulation. Programming has to be created for; accepting a potential date value from the screen, validating the data that was entered, calculate the number of days between two dates, figuring out the day of the week or even determine what todays date is. All these are tasks most COBOL programmers have had to perform at some time in their programming career.

The DateTimePicker control, along with the namespaces System.DateTime and System.TimeSpan can however save a COBOL developer a significant amount of time where date validation and manipulation is concerned. The DateTimePicker control restricts the input of data to valid dates, it can contain proper formatting and be set to ensure data ranges are valid before any data is accepted into the application. The System.DateTime namespace provides the developer with a set of properties and methods geared specifically towards date and time manipulation. The System.TimeSpan namespace allows us to determine the amount of time between two points as days, hours, or minutes. As we’ll see in the article existing date calculations that required numerous lengthy paragraphs to determine can now be handled with one or two lines of code.

The DateTimePicker example will show several different methods of determining date values and how they can be used with existing code.

WinForm

 

We’ve already created the WinForm we’ll be using. Remember, the intent is to learn how to work with the control and namespace, not create WinForms. Our WinForm was specifically designed to be simple and present only the basic information. It appears as:


For our example we have a starting date, which is a DateTimePicker control, and an ending date, which is another DataTimePicker control. The remaining fields are read-only textboxes that will be populated with data once the ‘Calculate’ button is selected. The intent is to show you, in the code, how to determine the values for each of these fields based on simply entering in some dates. To start, save the project to your hard drive, build the project and then execute it without debugging it.

When you select a start date, select a date that is in the future. Notice what happens after you have selected the start date; the end date is automatically updated to the same date. We’ll discuss how this happens in a bit but what this implies is I now have a date range that will always ensure my end-date will never be less than my start date. Let’s move on to the mechanics of the DateTimePicker control.

 

Properties

 

DateTimePicker, like all controls, has properties associated with them. Although there are many properties that can be manipulated we’ll discuss a few that may be used more often.

When working with properties the general format used to update a property is:

SETcontrolName::property TO {something}

Where: controlName is the name of the control

          Property is the name of the property to be manipulated

        {something} is specific to each property and can be text, Boolean, enums, etc.

We’re going to concentrate our discussion on the following properties:

 

Property

Description

Name

How the control is referenced programmatically

Format

Determines whether dates and times are displayed and in what format

CustomFormat

The custom format string used to display the date/time in the control

MaxDate

The maximum date that can be selected

MinDate

The minimum date that can be selected

For information on the remaining properties for a DateTimePicker control or to review the properties above please see the Visual COBOL documentation or Microsoft Developer Network (MSDN).

Name Property

The Name property is used to provide a unique name to the control so it can be accessed programmatically. For DateTimePicker I like to use the abbreviation ‘dtp’ in the first three positions and then follow that with something specific to what the DateTimePicker is for. I like to use camel-case (capital letter for the first letter of each word) for readability purposes. I would highly recommend establishing a naming convention to be used in your shop. The sample below shows the properties for the ‘Start Date’ object so I’ve used the name ‘dtpStartDate’.

Format Property

The DateTimePicker control allows the developer to define how the date and/or time will be displayed to the user. When selected the developer can choose either Short, Long, Custom or Time. When Short is selected only the date is shown. When Long is selected the date and time is shown. When Time is selected only the time of day is shown and when Custom is selected the information defined by the developer in the CustomFormat property is shown. For our example I’ve selected the ‘short’ format.



CustomFormat Property

Not all date and time formats are readily available to the developer to use in their presentation. The CustomFormat property enables a developer to select the characteristics best suited to their environment to request and display date and time information. In our example we formatted the date to contain the full name of the month(MMMM), the day(dd), year(yyyy) and the day of the week preceded by a dash(-dddd).



There are many combinations available to use for formatting your date and time. To review the options available please consult MSDN for the available options. The link I used was: http://msdn.microsoft.com/en-us/library/system.windows.forms.datetimepicker.customformat.aspx

MinDate Property

The MinDate property sets the minimum date that can be selected in the control. The default value is 1/1/1753, which I have left in the controls. The value can however be set programmatically via an event.



The End Date DateTimePicker control has had the MinDate property updated when the date was updated in the Start Date DateTimePicker. The event that enabled this was ‘ValueChanged’ and is executed any time the value of the control changes. The code to affect updating the MinDate property of the EndDate control is:

The ‘set’ statement uses the Value from the Start Date to update the minimum date of the end date. By setting the end date to be same as the start date we ensure the process hasn’t ended before it began. This simple statement and use of events can save a tremendous amount of processing time, not to mention coding, by ensuring the data being forward to the application for processing is valid.


MaxDate Property

MaxDate is the maximum date that can be selected for the control. The default value is 12/31/9998 and has been left in our example.


  


Calculating the data

Now that we have the controls defined and we understand the properties being used we need to calculate the data required and then display it back to the screen. A big portion of our job though has already been completed. Since we are using a DateTimePicker we do not have to edit the data coming in for format or validity as the .NET Framework assures us only valid data is entered. The control ensures we have valid dates and thanks to the CustomFormat property that the data is even in the right format.

We’re going to start by defining some variables in our method that will be used as working or holding fields.


If you’ll notice we have standard COBOL definitions for our start and end dates (ws-start-date and ws-end-date, respectively) along with the .NET representation of those same dates (start-date and end-date). By using both definitions I can utilize the power of .NET while preparing the data to be passed back to my existing procedural based COBOL programs.

One key technique is the use of the ‘type’ keyword. The ‘type’ keyword enables access to standard .NET assemblies. Type instructs the compiler that I am defining the field to be a standard .NET data definition of the following category. By doing this I can then take advantage of all the properties and methods associated with that namespace.

The first step in processing the data is to retrieve the data! The following code returns the value of the start date field.

 The first line of code retrieves the Value of the DateTimePicker control called StartDate and stores it into a field defined as a type DateTime (short for System.DateTime). If you’ll notice the parameter ‘Date’ at the end of the line. This instructs the runtime to return only the date portion of the date time picker, since that is all we are interested in at this time. By retrieving the data into a DateTime defined field we now have access to the structure of the data using the properties of the DateTime object. We can now directly access the data and store the right values for month, day and year into the standard COBOL data items. We do a similar step for the end date DateTimePicker:

Now that we have our start and end dates we can calculate the difference between the two dates. Because we stored them into DateTime data types we can utilize a variable defined as a TimeSpan type. A TimeSpan type represents an interval of time. It can be hours, minutes, seconds, milliseconds or days. By definition the time span data type understands the data being passed to it is of a DateTime data type and determining the time interval between the two dates is a simple subtraction statement coded as follows:



The TimeSpan type has several properties representing days, hours, minutes, seconds, ticks that we can now access and use in our programming. For our example we wanted to know the number of days between the two dates so we set a local storage variable (ws-nbr-of-days) to the Days property of the TimeSpan object we just calculated (ws-TimeSpan). So in two lines of code I have the difference in days between two dates in a local storage variable that I can now use in my calculations. In procedural COBOL how many lines of code would this require? The final line of code is to display the value back to the text box on the screen.

Working with Today

The previous examples used data that was entered onto the screen to determine values and results. The DateTime namespace also provides the ability to access data based on today. The following code retrieves the date for today and stores it into local storage variable defined as type DateTime.

Now that I have the date, I can format it:


There are numerous formats available. You can experiment with the different options to provide the format that works best for you. Trying using intelli-sense to see the different variations available.

You can also get the day of the week for Today:



Finally you can determine how many days are in the current month:


Wrap-Up

The DateTimePicker control along with the namespaces System.DateTime and System.TimeSpan offer a COBOL developer a huge toolbox to draw from. These routines can save you a significant amount of time and effort that would normally be spent to create and test code. These are ready to go and available to you, even if you’re working with procedural COBOL.

DateTimePicker.zip

The ZIP file has all the necessary source code for you to follow along and see how to update the properties we’ve described in the article. Read through the code; learn from it and use it in your projects. Even though we used a WinForm to present the information, the same concepts apply to WPF or WebForms. Yes there may be differences but this should at least serve as a starting point to help you figure out how to manipulate similar properties in the other presentation environments. Also, if you have a property you’re not sure how to work with send it to us. Chances are if you’re having questions someone else is also and we’d like to help you figure it out!

Happy Coding!

 

Tags: visual cobol, time, DateTimePicker, Date, .NET

Set up networked licensing with COBOL Server 2.1 to run native (non .NET) applications

$
0
0
Current Revision posted to Visual COBOL Knowledge Base by MF_Fano on 1/11/2016 3:49:04 PM
Created On:  03 October 2012

Problem:

Server for COBOL (formerly known as Application Server for Net Express) was using a different license mechanism and networked licensing (ASLMFNET). Is it possible to set up a similar networked licensing with COBOL Server 2.1 or Enterprise Server 2.1?

Resolution:

Here are the steps to set up networked licensing with COBOL Server 2.1 to run native (non .NET) applications.

[Server side]
1. Install COBOL Server 2.1 on the server
2. Install the license
3. Copy mfcesd.exe (MF CES Daemon) and mfcesdchk.exe (this checks if MF CES Daemon is running)
    a. In 32-bit Windows – from C:\Program Files\Common Files\SafeNet Sentinel\Sentinel RMS License Manager\WinNT to C:\Program Files\Micro Focus\COBOL Server\bin
    b. In 64-bit Windows – from C:\Program Files (x86)\Common Files\SafeNet Sentinel\Sentinel RMS License Manager\WinNT to C:\Program Files (x86)\Micro Focus\COBOL Server\bin
4. Extract msvcr100.dll and msvcr100d.dll from the attached SafeNetLic.zip into the “bin” folder of COBOL Server 2.1 – if these files are not found in C:\Windows\System32
5. Extract ces.ini from the attached SafeNetLic.zip into the “bin” folder of COBOL Server 2.1
6. Modify the value of lshost in ces.ini with the IP address or name of the server
7. Create a network share off the “bin” folder of COBOL Server 2.1 with Read permission to Everyone
8. Create a network share off the “bin64” folder of COBOL Server 2.1 with Read permission to Everyone– if running 64-bit applications

[Client side]
MF CES Daemon is required to run prior to run an application as it interacts with the MF License Manager for checking out a license. There are 2 recommended ways of starting MF CES Daemon and running the application:
1. Run a batch file to start MF CES Daemon and individual applications – Use and modify the attached the runit.bat file as follows:
    a. Set MFCES_INIT_LOCATION to point to the ces.ini file (e.g. \\ServerName\Share_bin\ces.ini)
    b. Set PATH to point to the location of the runtime files:
        i.  Replace \\ServerName\Share_bin to the network share created in Step 7
        ii. Remove “rem” in front of the next PATH setting and replace \\ServerName\Share_bin64 with the network share created in Step 8– if running 64-bit applications
   c. Set PATH to point to the location of the applications in the next PATH setting by replacing Location_of_Apps with the actual location
   d. Change the last line by replacing YourApp with the name of the application to be executed

-OR-

2. Install MF CES Daemon (only once) as a Windows service and run individual applications:
    a. Install and start MF CES Daemon as a Windows service:
        i.   Set MFCES_INIT_LOCATION as a system variable and to point to the ces.ini file (e.g. \\ServerName\Share_bin\ces.ini)
        ii.  Copy mfcesd.exe on the client machine’s local drive
        iii. Open a Command Prompt session
        iv. CD to the location of mfcesd.exe
        v.  Issue the following command to install MF CES Daemon as a Windows service:
            mfcesd -i
        vi. Issue the following command to start the MF CES Daemon service:
            mfcesd -start
    b. Set PATH as a system variable and to point to the location of the runtime files:
        • If running 32-bit applications, set PATH to point to the network share created in Step 7
        • If running 64-bit applications, set PATH to point to the network share created in Step 8 followed by the one created in Step 7
    c. Set PATH as a system variable to point to the location of the applications also
    d. Run the application

Notes:
    • ces.ini must be on a network location, and that is why we recommend creating it in the “bin” folder of COBOL Server 2.1
    • The above instructions are applicable to Enterprise Server 2.1
    • If you are running COBOL Server 2.0 or Enterprise Server 2.0, you will need to upgrade to version 2.1; otherwise, you still can follow the exact same instructions except that you will need to use mfcesd.exe and mfcesdchk.exe from the attached SafeNetLic.zip
    •
 The above instructions are specific to version 2.1 only. If you are running a higher version, you will need to follow the instructions from the documentations, and you must not use the files from the attached SafeNetLic.zip 

Incident #2592091

Attachments

Old KB# 36399
Tags: visual cobol, Enterprise, COBOL, Enterprise Developer, Enterprise Server

Adding Cultural Information to the DataTimePicker in Visual COBOL for .NET

$
0
0
Revision 1 posted to Visual COBOL Knowledge Base by RickM on 1/13/2016 5:26:52 PM

 

In a previous article we described how to utilize the .NET object ‘Date Time Picker’ in Visual COBOL. After reviewing the article Alwyn Royall (Mr), one of our UK Solutions Consultants provided some additional information about applying Cultural information to displaying dates. For those of you who work in a single location the thought of applying cultural information may not have crossed your mind. There are however applications that are used in a many different locations worldwide and the ability to present information, specifically date information, in a format they are used to seeing is huge benefit not only to the user but to the company receiving and processing the information. They are more assured the data will be correct and the end user finds the application easier to use.

WinForm

Alwyn has expanded the previously created WinForm to include a couple of new combo boxes. The new form now looks like the following:



If you will notice the bottom of the form there are three new items added:

 

Item

Description

Date Pattern

How to display the date time information

Country Format

What country specific format will be applied

Result

The output from applying the culture information

The process of executing the form has changed a bit with these additional fields. You still need to select the start and end dates at the top of the form but prior to clicking the “Calculate” button, but you now can select the pattern and country formats to apply to the date being presented in the result textbox.


Before we execute the form let’s take a look at the updates to the solution.

Variable declarations

In order to update the display of the date information to the selected culture some additional variables and data types are required. In the source code for the form we’ve separated these new variables so they are easier to locate and identify the specific updates applied.

Variable

Description

dt1

Hold variable for our date

dateFormat

Selected format from the combobox

dateCulture

Selected Culture to use from the combobox

dtFmt

The way the date will be displayed

dtCult

The specific culture to apply to the format

newCulture

Instantiated CultureInfo class

origCulture

Holder for the original culture setting

 

In order to fully understand the need for these variables let’s take a look at the new combo boxes that have been added to the form:

Date Pattern

The Date Pattern combo box will determine the format for the date to be displayed. The combo box has been predefined with the available formatting options for a date. If we look at the properties for the Date Pattern combo box we see the following:



Under the ‘Data’ area the ‘Items’ property has been updated to contain a collection of available selections for the combo box. Clicking on the “(Collection)” item yields the following display:



The values in the Collection editor represent the available formats available for a datetime data variable. This information was keyed in manually to create the list and if you’ll notice a specific format was used throughout:

 

Indicator space Description

The indicator corresponds to the formatting variables used by the DateTime data type and further information about the formats and data type can be found on MSDN at https://msdn.microsoft.com/en-us/library/az4se3k1.aspx


A space was used as a separator in the list

Description represents the way the date or time will be displayed.

When a selection is made from the combo box the value selected will be placed in the ‘dateFormat’ variable discussed earlier.

Country Format

Similar to the Date Pattern combo box, the Country Format combo box has a collection of available formats that can be applied. The properties for this combo box are:

Selecting the “(Collection)” ellipsis yields a similar string collection editor with data representative of the cultural information:



The format is identical to the Date Format data, an indicator followed by a space followed by a description of what the indicator is implying. In this instance though the indicator is not a single value but a combination of values separated by a dash.

The CultureInfo class specifies a unique name for each culture. The name is a combination of a two-letter lowercase culture code associated with a language and a two-letter uppercase subculture code associated with a country or region. For further information on the CultureInfo class see the MSDN documentation: https://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo(v=vs.110).aspx When a selection is made the value from the above table will be placed into the variable ‘dateCulture’ discussed earlier.

Now that we have shown the fields that will enable the selected date format and culture to be applied let’s talk about how to enable all this in our code.

Tying it all together

As with our data variables we’ve kept the update segment of code that applies the date and culture format information separate from our original code. The first thing we need is a date to manipulate! For our example we will use our StartDate that was selected at the top of the form. We can create a copy of it and store it in the ‘dt1’ variable with the following line of code:

Our next step is to determine what type of format to apply to the date. This information is contained in the date format combo box value that was selected prior to pressing ‘Calculate’. We have used a construct some of you may not be too familiar with, a ‘try-catch’ block. A ‘try-catch’ block is a coding construct distributed developers are very familiar with it, it basically says “try this bit of code, if it doesn’t work catch any errors here”.

Our example is ‘trying’ to set the dateFormat variable to the value from combo box that was selected prior to pressing the ‘Calculate’ button. The next line in the ‘try’ block says to move the first character found in position one to the variable dtFmt. This is the option that will be used when we format the date or time for display.

But what happens if you didn’t make a selection prior to pressing the ‘Calculate’ button? The ‘catch’ portion of the block says to move the letter ‘d’ to the dtFmt variable. This is in effect preventing an error from occurring by saying “if you didn’t make a selection use this as the default value”, it will also catch any invalid selections for your installation.

We next need to retrieve the specific culture information. This is done in a similar fashion with the following code:

Using another ‘try-catch’ block we first read the value that was selected into the variable ‘dateCulture’. The indicator starting in position one for a length of 5 is next moved into the variable ‘dtCult’. On the next line of code, the variable ‘dtCult’ is used as a parameter to update the cultural format to be used for our run-unit. The final line of code in the ‘try’ portion of the block is applying the new cultural information to the current thread or process, thus changing the way the date is formatted on the screen.

The final line of code ties it all together. We have already changed the cultural view of the date we now have to apply the updated formatting.

The textbox named “Result” (tbxResult) is updated to reflect the new format by applying the date format to the start date, dt1 in our sample. For our sample I have selected the long date format to be displayed in the Russian language. Prior to pressing the ‘Calculate’ button my screen appears as


And after pressing ‘Calculate’ the updated screen appears as:



Wrap-Up

Now you have seen the culture properties in use you might like to expand upon its use into currency and language presentations. Culture demonstrates one of the many benefits of utilizing the .NET platform in your application.

A big “Thank You” to Alwyn for his input and suggestion to applying cultural information to be used with the DateTimePicker control. The ability to work in multiple cultures, locations and languages greatly enhances the usefulness and longevity of your COBOL applications.

The ZIP file has all the necessary source code for you to follow along and see how to update the properties we’ve described in the article. Read through the code; learn from it and use it in your projects. Even though we used a WinForm to present the information, the same concepts apply to WPF or WebForms. Yes there may be differences but this should at least serve as a starting point to help you figure out how to manipulate similar properties in the other presentation environments. Also, if you have a property you’re not sure how to work with send it to us. Chances are if you’re having questions someone else is also and we’d like to help you figure it out!

If you’d like to try out the samples and don't have a copy of Micro Focus Visual COBOL, you can download the Personal Edition of Visual COBOL for free from this link: www.microfocus.com/visualcobolpe

Happy Coding!

 

Tags: visual cobol, COBOL .Net regional date format, COBOL, cultural information, culture, DateTimePicker, localization

Printing Duplex in Micro Focus Visual COBOL for .NET

$
0
0
Current Revision posted to Visual COBOL Knowledge Base by RickM on 1/27/2016 2:05:07 AM

Micro Focus has always tried to provide a full, in-depth development environment for COBOL developers. In previous releases of Micro Focus NetExpress it was possible to send files to the printer and have them print in duplex mode. The technique used was to call a Micro Focus supplied process using the following format

and passing it a series of parameters similar to the following

Unfortunately this process applies to a non-managed environment. More and more clients are moving to a managed environment under .NET. How then does one translate the above Micro Focus specific implementation of duplex printing to managed-COBOL?

The following article shows how to use the properties available in the Print Document class to enable duplex printing in .NET and adapt the Microsoft approach to handling printers.

Print Document Class

Before we dig into the specifics of implementing duplex printing we need to review the Print Document class. According to Microsoft the Print Document classDefines a reusable object that sends output to a printer, when printing from a Windows Forms application. I used the following link to obtain information on the class:  https://msdn.microsoft.com/en-us/library/system.drawing.printing.printdocument(v=vs.110).aspx. It is a part of the System.Drawing.Printing namespace.

The class we are going to be most concerned with is ‘PrinterSettings’ and the link for the properties to the class in MSDN is https://msdn.microsoft.com/en-us/library/system.drawing.printing.printersettings(v=vs.110).aspxThe PrinterSettings class, as the name implies, enables control of the settings related to a printer. Reviewing the class you’ll see there are over 20 properties you can access and alter. We are going to be concentrating on the ‘Duplex’ property.

If you click on the ‘Duplex’ property in the above link you’ll be redirected to a page that explains the Duplex property contains an enumeration of available settings to enable duplexing. Wonderful! But what are these values? In the description of the Duplex property is a link to the enumerated values and selecting it yields a table with the following values:

By default “most” printers are set to simplex. To enable duplex printing you simply need to readjust the setting prior to sending a file to the printer. Let’s see how to do that.

WinForm

If you’re familiar with my articles you know I like to use a WinForm as a container for the information to be presented. The information in this article however can be used without a WinForm by simply instantiating the classes found in our example. Yes I still used a WinForm because it does lend a way to walk through the information and present the ideas.

Our form is a very simple screen with a label and button. The button has a ‘Click’ event that will begin our process of setting up the environment to enable duplex printing.

Preparation

For our example we are going to read in a file that has a sufficient number of pages to generate a multi-page printout. We will need to setup a StreamReader to read the file in. The StreamReader is actually only used to get our data for printing, it isn’t necessary to enable the duplex printing. We also need to establish some variables that are going to be used by the PrintDocument methods when invoked. The variables we will need apply to the font to be used when the document is printed as well as what color the document will be printed in. These variables will be established as ‘global’ variables for the class, established in the class working-storage section as:

Notice the use of the ‘type’ identifier? This construct enables us to define variables as different object types as used in .NET. Distributed developers have been using this technique for a long time and Micro Focus has enabled this technique in Visual COBOL.

Button Click Event

Our process is started when the user clicks on the button, or a button-click-event. When this occurs the first thing we are going to do is a bit more housekeeping to prepare for the actual print event. The housekeeping details we are going to take care of are select the file we are going to print, set the font to be used for printing and set the font color. These three tasks are accomplished with the following code:

We next need to set the duplexing mode for the document to be printed. This is done in the ‘printDocument’ object we added to the form. Taking a look at the properties for this control show we have used the default name of ‘printDocument1’.

The properties we are going to set are not visible in the standard properties window. This is because the properties are actually part of an inherited class (PrinterSettings) the printDocument object uses. Let’s look at the code to set the duplex mode and then explain.

Before we enable the duplex mode for your printer, let’s make sure the printer you’ve chosen can indeed print in duplex mode. To do that we are going to check the ‘CanDumplex’ property. The CanDuplex property contains a Boolean value of ‘true’ or ‘false’. If the printer selected can indeed print in duplex mode we will then set it to vertical. If the printer cannot print in duplex then we well verify the duplex mode is turned off by setting it to ‘simplex’ mode. Using an ‘if’ statement the code to check for the ability to duplex and then setting the proper mode looks like:

We see our printDocument object, followed by the PrinterSettings class. As we enter the command intellisense provides us with the options available

Selecting Duplex we can see we can either get the setting for the current duplex mode or set it. We are going to set it so we select Duplex and continue with adding the rest of our line. Remember, the Duplex property takes an enumeration as a value. To set it we simply use the ‘type’ construct and point to the enumerator value we would like. In our case this is ‘System.Drawing.Printing.Duplex::Vertical’.

Now that we have set our duplex mode we next need to tell the runtime system what printer to send the output to. There are a number of ways to accomplish this. I chose to hard code a local printer in my environment that supports duplex mode

To update the sample to work in your environment, simply change the value in quotes from “HPD9C84D (HP Officeject Pro 8600)” to a printer that supports duplexing in your environment.

Time to Print!

We have set the properties to enable duplex printing, provided a file to print and printer to print to. The only left is to invoke the print function. This is done via printDocument control with the following line of code

When this line is executed the ‘PrintPage’ event is invoked for each page to be printed without invoking any user dialog. While the overall process may seem cumbersome once you understand it and have a working sample it can be re-used.

To begin we will define some variables that will control positioning of our page:

The variables are defined as:

Variable

Description

ypos

Position along the ‘y’ axis where we want to print the line

topMargin

As the name implies, the top margin of the page

line-count

How may lines have we printed

lines-per-page

How many lines do we want to print per page

printLine

The actual line of text to be printed

For our sample we have set the following values for each of the variables

Notice how we set the value for topMargin? We used the information that was passed into the method about the current printer.

We have wrapped our printing in a ‘perform’ loop. The loop will print a line a text until the number of lines printed exceeds the number of lines per page. The first line of code reads in a line to print from the file we defined earlier.

We then check using an ‘if’ statement if the line is null (empty) or if there is something to print. If there is something to print we need to determine where on the page we are by calculating the ypos value. The statement begins with the value of the top margin, adds in the number of lines printed times the height of the font being used

The formula is from the PrintDocument Print method on MSDN found at the following location https://msdn.microsoft.com/en-us/library/system.drawing.printing.printdocument.print(v=vs.110).aspx.

The actual line pf code to print the line is

We are invoking the DrawString method from the Graphics class. At the end of each page we need to determine if there is more to print. Remember, the method only prints a page of text at a time and needs to loop through if there is more to print. To check if there is more to print we check to see if the line of code we just read is not blank (or null). If it is not then we set the Boolean property ‘HasMorePages’ to true with the following code

There really isn’t anything to show as the outcome other than the printed file! Download the sample and review it, update it to work at your location and you’ll see the process really isn’t that bad to enable duplex printing at your location if your printers support it. While you’re working on that try some of the other updates (color, font) to the print stream and see how you can tailor your printed output. Once you understand how, you can then see how you can tailor specific lines based on the content of the line. The possibilities are endless. Experiment, learn and most of all… have fun doing it!

Wrap-Up

Duplex printing in .NET can be accomplished thanks to the framework and the classes available. Understanding which class to use and how to manipulate it will take some time but once you get the hang of it you’ll see as a COBOL developer you can accomplish the same tasks in COBOL as others can in C# or VB.NET or any of the other .NET languages.

PrintDuplex.zip

The ZIP file has all the necessary source code for you to follow along and see how to update the properties we’ve described in the article. Read through the code; learn from it and use it in your projects. Even though we used a WinForm to present the information, the same concepts apply to WPF or WebForms. Yes there may be differences but this should at least serve as a starting point to help you figure out how to manipulate similar properties in the other presentation environments. Also, if you have a property you’re not sure how to work with send it to us. Chances are if you’re having questions someone else is also and we’d like to help you figure it out!

If you’d like to try out the samples and don’t have a copy of Micro Focus Visual COBOL, you can download the Personal Edition of Visual COBOL for free from the following link: http://www.microfocus.com/visualcobolpe

Happy Coding!

Tags: visual cobol, COBOL, duplex, Printing, PrinterSettings

Incorrect SQL statement syntax near: WITH

$
0
0
Current Revision posted to Visual COBOL Knowledge Base by MF_Fano on 2/9/2016 6:24:19 PM

Problem:

The following complex query compiles fine in Net Express:

   EXEC SQL
      DECLARE cursor0 CURSOR FOR

      SELECT col1, col2,
      CASE WHEN ...
         THEN (SELECT COUNT(*) FROM table1 WHERE ...)
         ELSE (SELECT COUNT(*) FROM table1 WHERE...
            AND EXISTS (SELECT * FROM table2 WITH (NOLOCK) WHERE ...)) END,              CASE WHEN ... END
      FROM Table0

   END-EXEC.

When compiling the above in Visual COBOL 2.3 for Visual Studio, the following error occurs:

COBES0100 : Incorrect SQL statement syntax near: WITH

Resolution:

The issue has already been addressed in Visual COBOL 2.3 Hotfix1 that is available at the Product Updates page of the Micro Focus SupportLine site.

The fix is also included in the upcoming release of Visual COBOL 2.3 Update 1.

Calling Managed COBOL from un-managed code

$
0
0
Current Revision posted to Visual COBOL Knowledge Base by RickM on 2/12/2016 9:19:26 PM

The Microsoft .NET Framework and ‘managed’ code usage seem to be everywhere. More and more companies are adopting the use of managed frameworks to provide greater flexibility in their development environments and take advantage of the numerous features and benefits of the framework. But what if your shop isn’t on the road to .NET yet or fully? What if you have an existing COBOL environment that is not managed but in ‘native’ mode? How do you interact with managed code? How can you extend the use of your current application to reach out and utilize the features others have derived and published from the .NET Framework?

This article is an update of a previous article that was posted on the Micro Focus Community site in 2011 using NetExpress. This updated article will utilize the previous COBOL COM Server and client, but we will update the client from NetExpress to Visual COBOL. So let’s get started!

The Approach

The technology we will be using to enable the call to the managed environment is part of the .NET Interop technology and is known as COM Callable Wrapper or “CCW”. Basically what happens is the .NET class you create is registered as a COM server so the native COBOL program can call it as such using the COM support available in Visual COBOL. One benefit of this approach is that once the COM module is registered within the environment any client can then call the server. Our example we are using COBOL but you could also create a “C” or VB client to call the server.

The demonstration consists of two parts, a managed Visual COBOL project called VCCOMServer and a native Net Express project called NXCOMClient. We are going to import the NetExpress project into Visual COBOL for Visual Studio so the developer will be working in one environment, Visual Studio. Please unzip the attached file VCCOMDemo.zip onto your hard drive, retaining the folder structure of the zip file. We’re going to start with the server program since it is already created and will require minimal effort to update.

Managed Code

When you unzip the supplied file you will have a directory called “VCCOMDemo” and it will contain two sub-directories, “NXCOMClient” and “VCCOMServer”

                       

The VCCOMServer folder contains the managed code we will be using and defining as our COM server. Since the previous article was about using a managed environment we already have the managed code. If you select the VCCOMServer folder you will find a solution named “VCCOMServer.sln”, either double click on the solution file to open or from within Visual Studio navigate to the file and open it.

The VCCOMServer solution has a single program, VCCOMServer.cbl that implements an interface to the class. We are not going to spend time reviewing the class or interface as the intent is to demonstrate how to enable the code to be called as a COM Wrapper from within Visual Studio.

The secret is to tell Visual Studio when it builds the assembly, to register it as a COM assembly. This is conveniently done via a check box in the Project Properties. Double clicking on the ‘Properties’ entry and then selecting the ‘COBOL’ tab the following is presented

Click on the ‘Advanced…’ button to display the settings and you will see the following

In our example the checkbox for ‘Register for COM interop’ is already selected. By enabling this checkbox the build process will, once compilation is successful and completed, register the object as a COM service. Behind the scenes this is invoking “Regasm.exe” with the parameters of ‘tlb’ and ‘codebase’. The parameter ‘codebase’creates a Codebase entry in the registry. The Codebase entry specifies the file path for an assembly that is not installed in the global assembly cache or GAC. ‘tlb’ generates a type library from the specified assembly containing definitions of the accessible types defined within the assembly. You can review the ‘Regasm’ utility at https://msdn.microsoft.com/en-us/library/tzat5yw6(v=vs.110).aspx for further information.

Once you have this setting enabled, save your work and rebuild the solution. The object will be registered as a ‘COM’ object and available in your environment. One note of caution, if you experience the following error when trying to register the object

You will need to close Visual Studio and reopen it with Administrator privileges. Executing the Regasm utility requires a higher level of authentication and this is achieved by running Visual Studio as an Administrator.

One additional note, when you are ready to promote your updates to production you will need to execute Regasm for the module via the command line. The Visual Studio implementation of Regasm is enabled for development and testing, you will need to execute Regasm to register your module for production use. In order to execute the Regasm utility you will need Administrator rights.

You should be building your COM server assemblies using the exact target type of your client application when registering it for use with COM. This is because an in-process COM Server DLL is loaded into the process space of the client program so they need to be the same “bitism”. You should therefore use a target CPU of either x86 or x64 in your Visual Studio project properties and not “anyCPU” when it needs to be registered for COM.

Prior to using these assemblies on a production computer they must first be registered on that computer using the Regasm tool. The file “Regasm.exe” comes with the .NET framework installation and can be found in the Microsoft.NET framework folder. There are different versions of regasm.exe available depending on the version of the .NET Framework you are targeting and whether the assembly is compiled for x86 or x64.

You execute “regasm.exe” from an Administrative command prompt by using the hardcoded path to the correct version as shown below:
(for explanation of options please see https://msdn.microsoft.com/en-us/library/tzat5yw6(v=vs.110).aspx)

Targeting:

 .NET Framework 2.0, 3.0, or 3.5 for use with x86:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\regasm.exe myDLL.dll /codebase

.NET Framework 2.0, 3.0, or 3.5 for use with x64:
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\regasm myDLL.dll /codebase

.NET Framework 4.0 or higher for use with x86:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe myDLL.dll /codebase

.NET Framework 4.0 or higher for use with x64:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe myDLL.dll /codebase

 

The Client

Now that we have the server in place we can concentrate on the COBOL client that will be calling it. Our original solution was created using a previous version of the Micro Focus development environment called ‘NetExpress’. Visual COBOL is the current version of the NetExpress product reseated for the Visual Studio and Eclipse environments.

In order to utilize the Visual Studio environment we will need to upgrade the NetExpress project file to a Visual Studio solution. This is accomplished using the ‘Import NetExpress Project’ within Visual COBOL

By selecting ‘File’ then ‘New’ and finally ‘Import NetExpress Project’ a wizard will appear to walk you through the steps of importing and converting the NetExpress project to a Visual Studio Solution. Completing the steps will result in an updated project. We have left the original NetExpress project in the zip file in case you would like to test the import feature on your own.

The client program is a standard procedural based program utilizing what may be a few new features of the COBOL language for you.

The first item you see that you may not recognize is the ‘Class-Control’ header. The class-control header is an ISO2002 update to the language to enable the interaction with object-oriented classes and interface. In our example we are defining the server we would like to access, “VCCOMServer” as a class that is referenced by “$OLE$VCCOMServer.VCCOMServer”. If you’ll remember this was the name we assigned to our class-id in the server program.

The next item you may not have seen too often is the verb ‘invoke’. The ‘invoke’ verb is similar to the ‘call’ statement in procedural COBOL except it calls a method in an object oriented class. In our sample we are calling the methods “new”, “testVCstring”, “testVCint”, “testVCFloat” and “testVCGroup”.

There were no changes made to the client solution. We simply imported the NetExpress project, verified the properties and rebuilt the solution to generate the executable.

Execution

I placed a breakpoint at the first line of code in the Procedure Division and then began debugging the program.

If you’ll notice my ‘Autos’ window at the bottom, the object reference ‘anInstance’ is set to spaces because I haven’t executed a line of code as of this point. When I make the initial step and ‘instantiate’ the server I then have an address or pointer to a memory location where my copy of the server is

Instantiation is a formal way of saying I ‘made a copy of’ something. In this case I’ve made a copy of the VCCOMServer that I will be using and working with.

Stepping through the code we see the different variables come into view on the Autos window showing their values

Stepping through each of the method invocations we will see the following screen when complete

Wrap-Up

Calling managed COBOL from un-managed or native COBOL isn’t as scary or difficult as you may think. The secret is to make sure you register the managed code module for “COM interop”. In your existing procedural COBOL program you will need to add a ‘class-control’ header and then instantiate, or make a copy, of the module you wish to use. Then simply call the methods necessary using the ‘invoke’ verb. Using this technique you can also reference other managed code assemblies and provide new life to your procedural COBOL applications. Please remember when you are ready to promote your module to production to check with your IT Administrator about running the Regasm utility for your environment.

The ZIP file has all the necessary source code for you to follow along and see how to update the properties we’ve described in the article. Read through the code; learn from it and use it in your projects.

VCCOM.zip

If you’d like to try out the samples and don’t have a copy of Micro Focus Visual COBOL, you can download the Personal Edition of Visual COBOL for free from the following link: http://www.microfocus.com/visualcobolpe

Happy Coding!

Tags: visual cobol, COM, COBOL, native, interop, managed
Viewing all 214 articles
Browse latest View live




Latest Images