//**********************************************************************
// Use Fdx2.utl     // FDX aware object for displaying a table definition
//
// By Sture Andersen
//
// Create: Tue  09-02-2000
// Update:
//
//**********************************************************************
Use Fdx_Attr.nui // FDX compatible attribute functions
Use DBMS.utl     // Basic DBMS functions
Use GridUtil.utl // Grid and List utilities

#IFDEF IS$WINDOWS
 Use APS          // Auto Positioning and Sizing classes for VDF
 class cFDX.Display.FieldList is a aps.Grid
#ELSE
 Use App.utl      // Character Mode classes
 class cFDX.Display.FieldList is a List
#ENDIF
  register_function piFDX_Server returns integer
  register_function piMain_File  returns integer
  procedure construct_object integer img#
    forward send construct_object img#
    property integer piDisplayOldNumbers public 0
    on_key kuser send ToggleDisplayOldNumbers
    #IFDEF IS$WINDOWS
     send GridPrepare_AddColumn "#"        AFT_ASCII2
     send GridPrepare_AddColumn "Name"     AFT_ASCII15
     send GridPrepare_AddColumn "Type"     AFT_ASCII4
     send GridPrepare_AddColumn "Len"      AFT_ASCII5
     send GridPrepare_AddColumn "Offset"   AFT_ASCII5
     send GridPrepare_AddColumn "Idx"      AFT_ASCII3
     send GridPrepare_AddColumn "Relation" AFT_ASCII30
     send GridPrepare_Apply self
     set select_mode to no_select
    #ENDIF
    on_key key_ctrl+key_w send DoWriteToFile
  end_procedure
  procedure DoWriteToFile
    send Grid_DoWriteToFile self
  end_procedure
  #IFDEF IS$WINDOWS
   procedure add_item integer msg# string value#
     forward send add_item msg# value#
     set entry_state item (item_count(self)-1) to false
   end_procedure
  #ENDIF
  function sRelFieldName.ii integer file# integer field# returns string
    local integer fdx#
    local string file_name# field_name#
    ifnot file# function_return ""
    get piFDX_Server to fdx#
    if fdx# begin
      get FDX_AttrValue_FILELIST fdx# DF_FILE_LOGICAL_NAME file# to file_name#
      get FDX_AttrValue_FIELD fdx# DF_FIELD_NAME file# field# to field_name#
    end
    else begin
      get API_AttrValue_FILELIST DF_FILE_LOGICAL_NAME file# to file_name#
      if file_name# eq "" move ("FILE"+string(file#)) to file_name#
      if (DBMS_IsOpenFile(file#)) get API_AttrValue_FIELD DF_FIELD_NAME file# field# to field_name#
      else move ("FIELD"+string(field#)) to field_name#
    end
    function_return (file_name#+"."+field_name#)
  end_function
  procedure fill_list
    local integer file# fdx# max# field# st# type# len# dec# idx# iDisplayOldNumbers#
    local string str#
    get piMain_File to file#
    get piFDX_Server to fdx#
    get dynamic_update_state to st#
    set dynamic_update_state to false
    get FDX_AttrValue_FILE fdx# DF_FILE_NUMBER_FIELDS file# to max#
    get piDisplayOldNumbers to iDisplayOldNumbers#
    send delete_data
    for field# from 1 to max#
      send add_item msg_none (string(field#))
      send add_item msg_none (FDX_AttrValue_FIELD(fdx#,DF_FIELD_NAME,file#,field#))
      move (FDX_AttrValue_FIELD(fdx#,DF_FIELD_TYPE,file#,field#)) to type#
      send add_item msg_none (API_ShortFieldTypeName(type#))
      move (FDX_AttrValue_FIELD(fdx#,DF_FIELD_LENGTH,file#,field#)) to len#
      if type# eq DF_BCD begin
        move (FDX_AttrValue_FIELD(fdx#,DF_FIELD_PRECISION,file#,field#)) to dec#
        send add_item msg_none (string(len#-dec#)+"."+string(dec#))
      end
      else send add_item msg_none (string(len#))
      send add_item msg_none (FDX_AttrValue_FIELD(fdx#,DF_FIELD_OFFSET,file#,field#))
      move (FDX_AttrValue_FIELD(fdx#,DF_FIELD_INDEX,file#,field#)) to idx#
      if idx# send add_item msg_none (string(idx#))
      else    send add_item msg_none ""

      if iDisplayOldNumbers# begin
        move "(Old #) PhysLen: #" to str#
        replace "#" in str# with (FDX_AttrValue_FIELD(fdx#,DF_FIELD_OLD_NUMBER,file#,field#))
        replace "#" in str# with (FDX_AttrValue_FIELD(fdx#,DF_FIELD_NATIVE_LENGTH,file#,field#))
        send add_item msg_none str#
      end
      else send add_item msg_none (sRelFieldName.ii(self,FDX_AttrValue_FIELD(fdx#,DF_FIELD_RELATED_FILE,file#,field#),FDX_AttrValue_FIELD(fdx#,DF_FIELD_RELATED_FIELD,file#,field#)))
    loop
    set dynamic_update_state to st#
  end_procedure

  procedure ToggleDisplayOldNumbers
    set piDisplayOldNumbers to (not(piDisplayOldNumbers(self)))
    send fill_list
  end_procedure
end_class // cFDX.Display.FieldList

#IFDEF IS$WINDOWS
 class cFDX.Display.IndexList is a aps.Grid
#ELSE
 class cFDX.Display.IndexList is a List
#ENDIF
  procedure construct_object integer img#
    forward send construct_object img#
    set select_mode to auto_select
    #IFDEF IS$WINDOWS
     set Line_Width to 1 0
     set header_label item 0 to "#"
     set form_margin  item 0 to  8
     set highlight_row_state to true
//   set highlight_row_color to (rgb(0,255,255))
//   set current_item_color to (rgb(0,255,255))
     set CurrentCellColor     to clHighlight
     set CurrentCellTextColor to clHighlightText
     set CurrentRowColor      to clHighlight
     set CurrentRowTextColor  to clHighlightText
     set select_mode to no_select
     on_key knext_item send switch
     on_key kprevious_item send switch_back
    #ENDIF
    on_key key_ctrl+key_w send DoWriteToFile
  end_procedure
  procedure DoWriteToFile
    send Grid_DoWriteToFile self
  end_procedure
  #IFDEF IS$WINDOWS
   procedure add_item integer msg# string value#
     forward send add_item msg# value#
     set entry_state item (item_count(self)-1) to false
   end_procedure
  #ENDIF
  procedure fill_list
    local integer idx# file# fdx#
    send delete_data
    get piMain_File to file#
    get piFDX_Server to fdx#
    for idx# from 1 to 15
      send add_item msg_none ("Index "+string(idx#))
      ifnot (integer(FDX_AttrValue_INDEX(fdx#,DF_INDEX_NUMBER_SEGMENTS,file#,idx#))) set shadow_state item (item_count(self)-1) to true
    loop
    #IFDEF IS$WINDOWS
     set dynamic_update_state to true
    #ENDIF
  end_procedure
end_class // cFDX.Display.IndexList

#IFDEF IS$WINDOWS
 class cFDX.Display.IndexSegmentList is a aps.Grid
#ELSE
 class cFDX.Display.IndexSegmentList is a List
#ENDIF
  procedure construct_object integer img#
    forward send construct_object img#
    #IFDEF IS$WINDOWS
     set Line_Width to 3 0
     set header_label item 0 to "Field"
     set header_label item 1 to "U/C"
     set header_label item 2 to "Dsc"
     set form_margin  item 0 to 15
     set form_margin  item 1 to 3
     set form_margin  item 2 to 3
     set highlight_row_state to true
     set CurrentCellColor     to clHighlight
     set CurrentCellTextColor to clHighlightText
     set CurrentRowColor      to clHighlight
     set CurrentRowTextColor  to clHighlightText
//   set highlight_row_color to (rgb(0,255,255))
//   set current_item_color to (rgb(0,255,255))
     set select_mode to no_select
     on_key knext_item send switch
     on_key kprevious_item send switch_back
    #ENDIF
    on_key key_ctrl+key_w send DoWriteToFile
  end_procedure
  procedure DoWriteToFile
    send Grid_DoWriteToFile self
  end_procedure
  #IFDEF IS$WINDOWS
   procedure add_item integer msg# string value#
     forward send add_item msg# value#
     set entry_state item (item_count(self)-1) to false
   end_procedure
  #ENDIF
  procedure fill_list
    local integer max# seg# file# field# attr# fdx# value# idx#
    local string fname#
    send delete_data
    get piMain_File to file#
    get piFDX_Server to fdx#
    get piIndex to idx#
    move (FDX_AttrValue_INDEX(fdx#,DF_INDEX_NUMBER_SEGMENTS,file#,idx#)) to max#
    for seg# from 1 to max#
      move (FDX_AttrValue_IDXSEG(fdx#,DF_INDEX_SEGMENT_FIELD,file#,idx#,seg#)) to field#
      if field# move (FDX_AttrValue_FIELD(fdx#,DF_FIELD_NAME,file#,field#)) to fname#
      else move "RECNUM" to fname#
      send add_item msg_none fname#
      move (FDX_AttrValue_IDXSEG(fdx#,DF_INDEX_SEGMENT_CASE,file#,idx#,seg#)) to value#
      send add_item msg_none (if(value#=DF_CASE_IGNORED,"Yes","No"))
      move (FDX_AttrValue_IDXSEG(fdx#,DF_INDEX_SEGMENT_DIRECTION,file#,idx#,seg#)) to value#
      send add_item msg_none (if(value#=DF_DESCENDING,"Yes","No"))
    loop
    set dynamic_update_state to true
  end_procedure
end_class // cFDX.Display.IndexSegmentList
#IFDEF IS$WINDOWS
 class cFDX.Display.FileOtherList is a aps.Grid
#ELSE
 class cFDX.Display.FileOtherList is a List
#ENDIF
  procedure construct_object integer img#
    forward send construct_object img#
    #IFDEF IS$WINDOWS
     set Line_Width to 2 0
     set header_label item 0 to "Parameter"
     set header_label item 1 to "Value"
     set form_margin  item 0 to  30
     set form_margin  item 1 to  30
     set highlight_row_state to true
     set CurrentCellColor     to clHighlight
     set CurrentCellTextColor to clHighlightText
     set CurrentRowColor      to clHighlight
     set CurrentRowTextColor  to clHighlightText
//   set highlight_row_color to (rgb(0,255,255))
//   set current_item_color to (rgb(0,255,255))
     set select_mode to no_select
    #ENDIF
    property integer piDisplayRuntimeOnlies public 0
    on_key key_ctrl+key_w send DoWriteToFile
  end_procedure
  procedure DoWriteToFile
    send Grid_DoWriteToFile self
  end_procedure
  #IFDEF IS$WINDOWS
   procedure add_item integer msg# string value#
     forward send add_item msg# value#
     set entry_state item (item_count(self)-1) to false
   end_procedure
  #ENDIF
  procedure add_entry string param# string value#
    send add_item msg_none param#
    send add_item msg_none value#
  end_procedure
  procedure fill_list_help integer attr#
    local integer file# fdx#
    local string str#
    if (piDisplayRuntimeOnlies(self) or not(API_AttrRuntimeOnly(attr#))) begin
      get piMain_File to file#
      get piFDX_Server to fdx#
      move (FDX_AttrValue_FILE(fdx#,attr#,file#)) to str#
      send add_entry (API_Attr_DisplayName(attr#)) (API_Attr_DisplayValueName(attr#,str#))
    end
  end_procedure
  procedure fill_list
    send delete_data
    send API_AttrType_Callback ATTRTYPE_FILE msg_fill_list_help self
    #IFDEF IS$WINDOWS
     set dynamic_update_state to true
    #ENDIF
  end_procedure
end_class // cFDX.Display.FileOtherList

#IFDEF IS$WINDOWS
 object oFdxModalDisplayFileAttributes is a aps.ModalPanel label "Display table definition"
   property integer piFDX_Server public 0
   property integer piMain_File  public 0
   property integer piIndex      public 1
   on_key kcancel send close_panel
   set Locate_Mode to CENTER_ON_SCREEN
   set Border_Style to BORDER_THICK   // Make panel resizeable
   object oTabs is a aps.TabDialog
     set peAnchors to (anTop+anLeft+anBottom+anRight)
     object oTab1 is a aps.TabPage label "Fields"
       set p_Auto_Column to false
       object oFields is a cFDX.Display.FieldList
         set size to 160 0
         set peAnchors to (anTop+anLeft+anBottom+anRight)
         set peResizeColumn to rcAll
       end_object
     end_object
     register_object oIndexFields
     object oTab2 is a aps.TabPage label "Indices"
       object oIndexNo is a cFDX.Display.IndexList
         set size to 160 0
         set peAnchors to (anTop+anBottom)
         set peResizeColumn to rcAll
         procedure item_change integer from# integer to# returns integer
           local integer rval#
           forward get msg_item_change from# to# to rval#
           set piIndex to (rval#+1)
           send fill_list to (oIndexFields(self))
           send display_info
           procedure_return rval#
         end_procedure
       end_object
       set p_auto_column to false
       object oIndexFields is a cFDX.Display.IndexSegmentList
         set peAnchors to (anTop+anLeft+anBottom+anRight)
         set peResizeColumn to rcAll
         set size to 160 0
       end_object
       object oFrm1 is a aps.Form label "Key length:" abstract aft_numeric4.0 snap sl_right_space
         set peAnchors to (anTop+anRight)
         set object_shadow_state to true
       end_object
       object oFrm2 is a aps.Form label "Levels:" abstract aft_numeric4.0 snap sl_down
         set peAnchors to (anTop+anRight)
         set object_shadow_state to true
         set label_offset to 0 0
         set label_justification_mode to jmode_right
       end_object
       object oFrm3 is a aps.Form label "Batch:" abstract aft_ascii4 snap sl_down
         set peAnchors to (anTop+anRight)
         set object_shadow_state to true
         set label_offset to 0 0
         set label_justification_mode to jmode_right
       end_object
       procedure display_info
         local integer idx# attr#
         local integer file# fdx#
         get piMain_File to file#
         get piFDX_Server to fdx#
         get piIndex to idx#
         move (FDX_AttrValue_INDEX(fdx#,DF_INDEX_KEY_LENGTH,file#,idx#)) to attr#
         set value of (oFrm1(self)) item 0 to attr#
         move (FDX_AttrValue_INDEX(fdx#,DF_INDEX_LEVELS,file#,idx#)) to attr#
         set value of (oFrm2(self)) item 0 to attr#
         move (FDX_AttrValue_INDEX(fdx#,DF_INDEX_TYPE,file#,idx#)) to attr#
         if attr# eq DF_INDEX_TYPE_ONLINE set value of (oFrm3(self)) item 0 to "No"
         else                             set value of (oFrm3(self)) item 0 to "Yes"
       end_procedure
     end_object
     object oTab3 is a aps.TabPage label "Attributes"
       object oOther is a cFDX.Display.FileOtherList
         set size to 160 0
         set peAnchors to (anTop+anLeft+anBottom+anRight)
         set peResizeColumn to rcAll
       end_object
     end_object
   end_object
   object oBtn is a aps.Multi_Button
     on_item t.btn.close send close_panel
     set peAnchors to (anBottom+anRight)
   end_object
   send aps_locate_multi_buttons
   procedure run.ii integer obj# integer file#
     set piFDX_Server to obj#
     set piMain_File  to file#
     send fill_list to (oFields(oTab1(oTabs(self))))
     set piIndex to 1
     send fill_list to (oIndexNo(oTab2(oTabs(self))))
     send fill_list to (oIndexFields(oTab2(oTabs(self))))
     send display_info to (oTab2(oTabs(self)))
     send fill_list to (oOther(oTab3(oTabs(self)))) obj#
     send popup
   end_procedure
 end_object
 send aps_SetMinimumDialogSize (oFdxModalDisplayFileAttributes(self))
#ELSE
/Fdx2.hdr
ÉÍDisplay table definition:ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
/Fdx2.hdr_btn
Alt+Í_Í_Í_Í»
/Fdx2.Fields
º                                                                    º
º   # Name            Typ Len   OffSet Idx Relation                  º
º __. _C_____________ ___ _____ ____.  _.  _________________________ º
º __. _C_____________ ___ _____ ____.  _.  _________________________ º
º __. _C_____________ ___ _____ ____.  _.  _________________________ º
º __. _C_____________ ___ _____ ____.  _.  _________________________ º
º __. _C_____________ ___ _____ ____.  _.  _________________________ º
º __. _C_____________ ___ _____ ____.  _.  _________________________ º
º __. _C_____________ ___ _____ ____.  _.  _________________________ º
º                                                                    º
/Fdx2.IndexNo
º                 ÿ
º ___________     ÿ
º ___________     ÿ
º ___________     ÿ
º ___________     ÿ
º ___________     ÿ
º ___________     ÿ
º ___________     ÿ
º ___________     ÿ
º                 ÿ
/Fdx2.IndexFields
                          ÿ
Field           U/C Dsc   ÿ
_______________ ___ ___   ÿ
_______________ ___ ___   ÿ
_______________ ___ ___   ÿ
_______________ ___ ___   ÿ
_______________ ___ ___   ÿ
_______________ ___ ___   ÿ
_______________ ___ ___   ÿ
                          ÿ
/Fdx2.IndexInfo
                       º
Index length: _____    º
                       º
Index levels: _____    º
                       º
Batch.......: ___      º
                       º
                       º
                       º
                       º
/Fdx2.Other
º                                                                    º
º Parameter                     Value                                º
º _____________________________ ____________________________________ º
º _____________________________ ____________________________________ º
º _____________________________ ____________________________________ º
º _____________________________ ____________________________________ º
º _____________________________ ____________________________________ º
º _____________________________ ____________________________________ º
º _____________________________ ____________________________________ º
º                                                                    º
/Fdx2.Btn
º                                            ___ ___  _____________  º
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
/*
 indicate filedef.rotate_up? false
 object oFdxModalDisplayFileAttributes is a app.ModalClient Fdx2.hdr
   set location to 5 7 absolute
   property integer piFDX_Server public 0
   property integer piMain_File  public 0
   on_key kcancel send cancel
   on_key key_alt+key_1 send activate_tab1
   on_key key_alt+key_2 send activate_tab2
   on_key key_alt+key_3 send activate_tab3
   on_key key_ctrl+key_pgup send request_previous_tab
   on_key key_ctrl+key_pgdn send request_next_tab
   on_key kuser send xxxxx
   procedure xxxxx
     send obs (piFDX_Server(self))
   end_procedure
   property integer piCurrentTab public 0
   property integer piIndex      public 1
   object oHdr_Btn is a Button Fdx2.hdr_btn
     set location to 0 58 relative
     set focus_mode to pointer_only
     item_list
       on_item "1" send activate_tab1
       on_item "2" send activate_tab2
       on_item "3" send activate_tab3
     end_item_list
   end_object

   procedure OnActivate integer tab#
     local integer obj#
     move (oHdr_Btn(self)) to obj#
     set value of obj# item 0 to "1"
     set value of obj# item 1 to "2"
     set value of obj# item 2 to "3"
     set value of obj# item (tab#-1) to ""
     set piCurrentTab to tab#
   end_procedure

   procedure request_previous_tab
     local integer tab#
     get piCurrentTab to tab#
     decrement tab#
     if tab# eq 0 move 3 to tab#
     if tab# eq 1 send activate_tab1
     if tab# eq 2 send activate_tab2
     if tab# eq 3 send activate_tab3
   end_procedure
   procedure request_next_tab
     local integer tab#
     get piCurrentTab to tab#
     increment tab#
     if tab# eq 4 move 1 to tab#
     if tab# eq 1 send activate_tab1
     if tab# eq 2 send activate_tab2
     if tab# eq 3 send activate_tab3
   end_procedure

   object oFields is a cFDX.Display.FieldList Fdx2.Fields
     set location to 1 0 relative
     procedure rotate_up
       forward send rotate_up
       send OnActivate 1
     end_procedure
   end_object

   register_object oIndexInfo
   register_object oIndexFields
   object oIndexNo is a cFDX.Display.IndexList Fdx2.IndexNo
     set location to 1 0 relative
     procedure item_change integer from# integer to# returns integer
       local integer rval#
       forward get msg_item_change from# to# to rval#
       set piIndex to (rval#+1)
       send fill_list to (oIndexFields(self))
       send display_info to (oIndexInfo(self))
       procedure_return rval#
     end_procedure
     procedure rotate_up
       [~filedef.rotate_up?] send rotate_up_group
       [ filedef.rotate_up?] forward send rotate_up
     end_procedure
   end_object
   object oIndexFields is a cFDX.Display.IndexSegmentList Fdx2.IndexFields
     set location to 1 19 relative
     procedure rotate_up
       [~filedef.rotate_up?] send rotate_up_group
       [ filedef.rotate_up?] forward send rotate_up
     end_procedure
   end_object
   object oIndexInfo is a Form Fdx2.IndexInfo
     set location to 1 46 relative
     set skip_state to true
     item_list
       on_item "" send none
       set shadow_state to true
       on_item "" send none
       set shadow_state to true
       on_item "" send none
       set shadow_state to true
     end_item_list
     procedure display_info
       local integer idx# attr#
       local integer file# fdx#
       get piMain_File to file#
       get piFDX_Server to fdx#
       get piIndex to idx#
       move (FDX_AttrValue_INDEX(fdx#,DF_INDEX_KEY_LENGTH,file#,idx#)) to attr#
       set value item 0 to attr#
       move (FDX_AttrValue_INDEX(fdx#,DF_INDEX_LEVELS,file#,idx#)) to attr#
       set value item 1 to attr#
       move (FDX_AttrValue_INDEX(fdx#,DF_INDEX_TYPE,file#,idx#)) to attr#
       if attr# eq DF_INDEX_TYPE_ONLINE set value item 2 to "No"
       else set value item 2 to "Yes"
     end_procedure
     procedure rotate_up
       [~filedef.rotate_up?] send rotate_up_group
       [ filedef.rotate_up?] forward send rotate_up
     end_procedure
   end_object
   procedure rotate_up_group
     indicate filedef.rotate_up? true
     send rotate_up to (oIndexNo(self))
     send rotate_up to (oIndexFields(self))
     send rotate_up to (oIndexInfo(self))
     indicate filedef.rotate_up? false
     send OnActivate 2
   end_procedure

   object oOther is a cFDX.Display.FileOtherList Fdx2.Other
     set location to 1 0 relative
     procedure rotate_up
       forward send rotate_up
       send OnActivate 3
     end_procedure
   end_object

   procedure activate_tab1
     send activate to (oFields(self))
   end_procedure
   procedure activate_tab2
     send activate to (oIndexNo(self))
   end_procedure
   procedure activate_tab3
     send activate to (oOther(self))
   end_procedure

   object oBtn is a app.Button Fdx2.Btn
     set location to 11 0 relative
     item_list
       on_item "" send request_previous_tab
       on_item "" send request_next_tab
       on_item t.btn.close send cancel
     end_item_list
   end_object

   procedure run.ii integer obj# integer file#
     local integer grb#
     set piFDX_Server to obj#
     set piMain_File  to file#
     send fill_list to (oFields(self))
     set piIndex to 1
     send fill_list to (oIndexNo(self))
     send fill_list to (oIndexFields(self))
     send display_info to (oIndexInfo(self))
     send fill_list to (oOther(self)) obj#
     ui_accept self to grb#
   end_procedure
 end_object // oFdxModalDisplayFileAttributes
#ENDIF

object oABCDEFG is a cArray NO_IMAGE
  register_function iFdxIsEncapsulated returns integer
end_object

register_function piMainFile returns integer
procedure FDX_ModalDisplayFileAttributes global integer oFDX# integer file#
  local integer open# was_open# lbIsEncapsulated
  ifnot oFDX# begin
    move (DBMS_IsOpenFile(file#)) to was_open#
    if was_open# move 1 to open#
    else move (DBMS_OpenFile(file#,DF_SHARE,0)) to open#
  end
  else begin
    move 1 to open#
    if file# eq 0 begin
      // File not specified means the oFDX# holds only one file
      get iFdxIsEncapsulated of oFDX# to lbIsEncapsulated
      if lbIsEncapsulated begin
        send obs "Missing file number argument"
        move 0 to open#
      end
      else get piMainFile of oFDX# to file#
    end
  end
  if open# send run.ii to (oFdxModalDisplayFileAttributes(self)) oFDX# file#
  else send obs "Table is not available"
  ifnot oFDX# if (open# and not(was_open#)) close file#
end_procedure

// Test code
//
// open prtcomm
// send FDX_DisplayFileAttributes 0 PrtComm.File_Number