Страница 1 из 1

Кол-во полей в структуре данных

Добавлено: 28 Август 2020, 17:04
Игорь Столяров
Привет всем !

Простой вопрос: зя как-нибудь определить кол-во полей в произвольной структуре (GROUP, QUEUE) данных ?
Сейчас это тупо делается перебором:

Код: Выделить всё

        Loc:IColumn = 1
        Loop While(Who(Loc:MyQueue,Loc:IColumn) <> '')
          Loc:IColumn += 1
        end
        Loc:IColumn -= 1  ! < --- Кол-во полей в структуре данных Loc:MyQueue
Может быть я чего-то не знаю ? Заранее спасибо ! :)

Кол-во полей в структуре данных

Добавлено: 28 Август 2020, 17:56
Дед Пахом
Встроенной функции нет, надо перебором, само собой написать процедуру для произвольной группы. Только Ваш перебор для произвольной группы не годится - бывают поля без метки, для них Who() вернёт пустую строку.

Кол-во полей в структуре данных

Добавлено: 28 Август 2020, 18:25
Yufil
What надо вместо Who

Код: Выделить всё

A  Any
LOOP Count# = 1 to 10000
   A &= What( MyGroup, Count#) 
   IF A &= NULL THEN Break. 
END 
Return (Count# - 1)
 

Кол-во полей в структуре данных

Добавлено: 28 Август 2020, 18:49
Игорь Столяров
Вон оно как повернулось-то ... :(
Спасибо, пошёл переделывать. :)

Кол-во полей в структуре данных

Добавлено: 28 Август 2020, 22:20
Дед Пахом
Нашёл у себя такой вариант, который учитывает и вложенные группы, и массивы внутри группы:

Код: Выделить всё

FieldCount                    PROCEDURE(*GROUP pGrp)
fldNdx                          LONG, AUTO
fldRef                          ANY
nestedGrp                       &GROUP
nFields                         LONG(0)
  CODE
  LOOP fldNdx = 1 TO 9999
    fldRef &= WHAT(pGrp, fldNdx)
    IF fldRef &= NULL
      !end of group
      BREAK
    END
  
    IF ISGROUP(pGrp, fldNdx)
      !- recursively get number of fields from nested group
      nestedGrp &= GETGROUP(pGrp, fldNdx)
      nFields += FieldCount(nestedGrp)
    ELSE
      nFields += HOWMANY(pGrp, fldNdx)
    END
  END

  RETURN nFields

Кол-во полей в структуре данных

Добавлено: 29 Август 2020, 14:41
Игорь Столяров
Спасибо, "сделал" ! :) Заодно узнал о назначении и применении нескольких операторов.
Не, я конечно знал о существовании ISGROUP, GETGROUP, HOWMANY - но это был параллельный мир.
Да и вообще, где появляется рекурсия, там Игоря нет. :)

Кол-во полей в структуре данных

Добавлено: 04 Сентябрь 2020, 6:14
IKSoft
на 6.5 работает это:

Код: Выделить всё

tcIO.mGetMaxFields       FUNCTION (Queue p_Q)              
tgQue  group,type
PRecBuff long
PQueHead long
Unknown  long
RecSize  long
      end

tgQueHeader   group,type
id             short
RecSize        long
Fields         long
DescrSize      long
       end

grp   group
ptQueue  &Queue
ptr      long,over(ptQueue)
     end

pgQue        &tgQue
pgQueHeader  &tgQueHeader
  CODE                                            

  grp.ptQueue &= p_Q
  if (grp.ptQueue &= NULL)
     return(-1).
  pgQue &= (grp.ptr)
  pgQueHeader &= (pgQue.pQueHead)

  return(pgQueHeader.Fields)

tcIO.mGetMaxFields       FUNCTION (*group p_gG)     
tgGRP  group,type
pRecBuff long
pGrpHead long
RecSize  long
      end

tgGRPHeader   group,type
id             short
RecSize        long
Fields         long
DescrSize      long
       end

gPtr   group
pG         &group
       end

pgGRP        &tgGrp
pgGRPHeader  &tgGRPHeader

  CODE                                            

  gPtr.pG &= p_gG
  pgGrp &= (address(gPtr))
  pgGrpHeader &= (pgGrp.pGrpHead)
  return(pgGrpHeader.Fields)


Кол-во полей в структуре данных

Добавлено: 10 Ноябрь 2022, 10:49
Игорь Столяров
Дед Пахом писал(а): 28 Август 2020, 22:20 Нашёл у себя такой вариант, который учитывает и вложенные группы
Всё работало ровно до того, как появились вложенные группы ... :(
Простой пример:

Код: Выделить всё

Gr3         Group,Type
Fi3_1         Long
            end

Gr2         Group,Type
Fi2_1         Group(Gr3).
Fi2_2         Group(Gr3).
Fi2_3         Long
            end

Gr1         Group
Fi1_1         Long
Fi1_2         Group(Gr2).
Fi1_3         Long
            end
   Code
   Message(FieldCount(Gr1))  ! = 12 
Я насчитал 8 полей. :shock:
Вставлял в цикл перебора: Message(Who(pGrp, fldNdx)) - не понимаю как оно с рекурсией их обходит. :(
Если можно объяснить результат - буду благодарен ... :)

Кол-во полей в структуре данных

Добавлено: 10 Ноябрь 2022, 15:38
Дед Пахом
Это потому, что внутренние поля групп принадлежат и внешним группам. Например, Fi3_1 принадлежит группам Fi2_1 и Fi2_2, а также внешней группе Fi1_2, и даже самой внешней Gr1. В справке по WHAT приводится пример:

Код: Выделить всё

MyGroup  GROUP
F1        LONG(3)             !Field number 1
F2        SHORT               !Field number 2
F3        STRING(30)          !Field number 3
InGroup    GROUP              !Field number 4
F1          LONG              !Field number 5
F2          SHORT(2)          !Field number 6
F3          STRING(30),DIM(2) !Field number 7
F4          LONG,DIM(3,3)     !Field number 8
F5          ANY
          END
         END

  CODE
  CurrentField &= WHAT(MyGroup,1)   !Returns contents of MyGroup.F1 (3)
  CurrentField &= WHAT(MyGroup,6)   !Returns contents of MyGroup.Ingroup.F2 (2)
  CurrentField &= WHAT(MyGroup,7)   !Returns contents of MyGroup.Ingroup.F3[1]
Я FieldCount использую для пропуска вложенных полей:

Код: Выделить всё

    IF ISGROUP(pGrp, fldNdx)
      !- recursively add fields from nested group
      nestedGrp &= GETGROUP(pGrp, fldNdx)
      SELF.From(nestedGrp, fldPos)
      cnt = FieldCount(nestedGrp)  !- skip fields from nested groups
      fldNdx += cnt
      fldPos += cnt
    ELSE

Кол-во полей в структуре данных

Добавлено: 10 Ноябрь 2022, 17:37
Игорь Столяров
Спасибо. Понял. Точнее не понял, но буду разбираться ... :)
Еще со времён программирования на Pascal запомнил, что где рекурсия - там всегда что-то не так ... ;)

Кол-во полей в структуре данных

Добавлено: 10 Ноябрь 2022, 19:07
finsoftrz
Я рекурсию тоже не воспринимаю. Поэтому обхожусь без нее. Например, можно родителей в кьюшку засовывать по типу стека. Телодвижений больше, зато код мне понятный.