ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Move portion of DS into a varchar

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

  • Move portion of DS into a varchar

    Hi All,

    I have to work with Nested array, but since I can't declare a vardim ds, I put into my first Ds a varchar field, and then I want to move the part of my nested Dim Ds valorized into this varchar field, I tried this:

    Code:
    **free
    Ctl-Opt
    DftName(TESTDS)
    dftactgrp(*no) actgrp('QILE')
    option(*nounref :*srcstmt :*nodebugio)
    datfmt(*iso) timfmt(*iso)
    debug
    Text('Test Ds')
    alwnull(*usrctl);
    Dcl-Ds DsDetail LikeDs(Detail_Template) dim(10);
    Dcl-Ds DsResult Qualified;
      DetailChar VarChar(1000);
    End-Ds DsResult;
    Dcl-ds Detail_Template Qualified Template;
      ContractGroup Varchar(100);
      MarketRisk Float(8);
      EntryNum Int(10);
      EntryChar Varchar(1000);
    End-ds Detail_Template;
    Dcl-Ds DsEntry Qualified ;
      Arr LikeDs(Entry_Template) dim(10);
    End-Ds DsEntry ;
    Dcl-ds Entry_Template Qualified Template;
      key Varchar(30);
      Value Varchar(30);
    End-ds Entry_Template;
    Dcl-s Idx Int(10);
    Dcl-s WorkField Varchar(1000);
    //
    DsDetail(1).ContractGroup = 'pippo';
    DsDetail(2).ContractGroup = 'pluto';
    DsDetail(3).ContractGroup = 'paperino';
    DsDetail(1).Entrynum = 2;
    DsDetail(1).MarketRisk = 8.12903;
    DsDetail(2).MarketRisk = 9.12903;
    DsDetail(3).MarketRisk = 10.12903;
    DsEntry.Arr(1).Key = 'key1';
    DsEntry.Arr(2).Key = 'key2';
    DsEntry.Arr(1).Value = 'value2';
    DsEntry.Arr(2).Value = 'Value3';
    WorkField = DsEntry;
    WorkField = %Subarr(DsEntry.Arr :1 :DsDetail(1).Entrynum);
    //DsDetail(1).EntryChar = %SubArr(DsEntry.Arr : 1 :DsDetail(1).EntryNum);
    *inlr = *on;
    But the compiler sayd me: *RNF5343 30 1 Array has too many omitted indexes; specification is ignored.

  • #2
    I don't see how you think this helps you in any way. Storage for a varchar is allocated at the maximum length (except in some cases when a varch is in a table) regardless of usage - so you save nothing and add a level of complexity to your task that makes it harder for others to understand. Actually it costs you more storage since a varchar is 2 (or 4) bytes longer than its maximum length to accommodate the length information.

    Why are you trying to do this? If you really have a need for a variable length array of arbitrary length then there are open source solutions that will enable you to achieve this.

    Comment


    • #3
      HI Jon,

      My idea is: the DsEntry probably have 3 or 4 entries, so If my field
      DsDetail(1).EntryChar I'll put only the entries the exists I reduce the space allocated from all the DsEntry to the DsEntry really allocated.
      Do you have an example about the other solutions you tell me?
      Many thanks.

      Comment


      • #4
        I figured that was what you were trying to do - but it doesn't work because a varchar(100) occupies 102 bytes of storage no matter whether its current length is 0 or 100. They are not varying length strings in the way that they may be represented in other languages (i.e. by null termination).

        If you want to reduce the storage footprint then use a based array and use %Alloc to assign storage as and when needed. The series of articles listed here https://www.itjungle.com/tag/teraspace/ talk to using Teraspace to handle arrays that exceed RPG's 16Mb limit for a defined DS. But as long as your maximum fits within RPG's limit you can just use regular storage and use the RPG's Dim(xxxxx) where xxxxx is the biggest it will ever be - use %Alloc to allocate storage and keep track of how many elements you currently have space for. Ted Holt has an example here: https://www.itjungle.com/2006/05/10/fhg051006-story02/

        As to OS offerings Mihael Schmidt has a couple which he describes here http://blog.rpgnextgen.com/blog/2017...vs-linked-list - there are others but I can't rcall who/where right now.

        Comment


        • #5
          Code:
          **free
          Ctl-Opt
          DftName(TESTDS)
          dftactgrp(*no) actgrp('QILE')
          option(*nounref :*srcstmt :*nodebugio)
          datfmt(*iso) timfmt(*iso)
          debug
          Text('Test Ds')
          alwnull(*usrctl);
          
          Dcl-Ds DsDetail LikeDs(Detail_Template) dim(10);
          
          Dcl-Ds DsResult Qualified;
            DetailChar VarChar(1000);
          End-Ds DsResult;
          
          Dcl-ds Detail_Template Qualified Template;
            ContractGroup Varchar(100);
            MarketRisk Float(8);
            EntryNum Int(10);
            EntryChar Varchar(1000);
          End-ds Detail_Template;
          
          Dcl-Ds DsEntry Qualified ;
            Arr LikeDs(Entry_Template) dim(10);
          End-Ds DsEntry ;
          
          Dcl-ds Entry_Template Qualified Template;
            key Varchar(30);
            Value Varchar(30);
          End-ds Entry_Template;
          
          Dcl-DS Workfield1 LikeDS(DSEntry);
          
          Dcl-s Idx Int(10);
          Dcl-s WorkField Varchar(1000);
          Dcl-S Lgth Int(10);
          //
          DsDetail(1).ContractGroup = 'pippo';
          DsDetail(2).ContractGroup = 'pluto';
          DsDetail(3).ContractGroup = 'paperino';
          DsDetail(1).Entrynum = 2;
          DsDetail(1).MarketRisk = 8.12903;
          DsDetail(2).MarketRisk = 9.12903;
          DsDetail(3).MarketRisk = 10.12903;
          DsEntry.Arr(1).Key = 'key1';
          DsEntry.Arr(2).Key = 'key2';
          DsEntry.Arr(1).Value = 'value2';
          DsEntry.Arr(2).Value = 'Value3';
          WorkField = DsEntry;
          WorkField1.Arr = %Subarr(DsEntry.Arr :1 :DsDetail(1).Entrynum);
          Workfield = %Trim(Workfield1);
          Lgth = %Len(Workfield);
          //DsDetail(1).EntryChar = %SubArr(DsEntry.Arr : 1 :DsDetail(1).EntryNum);
          *inlr = *on;
          This will have Workfield reflect the data as VARCHAR - but if your goal is to reduce the use of memory it doesn't work, in fact it makes it worse as you have to copy the data structure into a character string as well as what Jonboy has already mentioned.

          If the goal is to reduce the use of memory to reflect actual usage, the use of allocated storage is much more effective since you allocate memory on a need to basis rather than allocating memory to handle the worst case scenario - or alternatively writing the data to a table as you go.

          Comment

          Working...
          X