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

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Ответить
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7330
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

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

Сообщение Игорь Столяров »

Привет всем !

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

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

        Loc:IColumn = 1
        Loop While(Who(Loc:MyQueue,Loc:IColumn) <> '')
          Loc:IColumn += 1
        end
        Loc:IColumn -= 1  ! < --- Кол-во полей в структуре данных Loc:MyQueue
Может быть я чего-то не знаю ? Заранее спасибо ! :)
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3131
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 10 раз
Поблагодарили: 28 раз
Контактная информация:

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

Сообщение Дед Пахом »

Встроенной функции нет, надо перебором, само собой написать процедуру для произвольной группы. Только Ваш перебор для произвольной группы не годится - бывают поля без метки, для них Who() вернёт пустую строку.
С уважением, ДП
Yufil
Ветеран движения
Сообщения: 1277
Зарегистрирован: 16 Май 2006, 14:34
Контактная информация:

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

Сообщение Yufil »

What надо вместо Who

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

A  Any
LOOP Count# = 1 to 10000
   A &= What( MyGroup, Count#) 
   IF A &= NULL THEN Break. 
END 
Return (Count# - 1)
 
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7330
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

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

Сообщение Игорь Столяров »

Вон оно как повернулось-то ... :(
Спасибо, пошёл переделывать. :)
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3131
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 10 раз
Поблагодарили: 28 раз
Контактная информация:

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

Сообщение Дед Пахом »

Нашёл у себя такой вариант, который учитывает и вложенные группы, и массивы внутри группы:

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

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
С уважением, ДП
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7330
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

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

Сообщение Игорь Столяров »

Спасибо, "сделал" ! :) Заодно узнал о назначении и применении нескольких операторов.
Не, я конечно знал о существовании ISGROUP, GETGROUP, HOWMANY - но это был параллельный мир.
Да и вообще, где появляется рекурсия, там Игоря нет. :)
За теми кто отстал - не возвращаться. (С) Кодекс
IKSoft
Посетитель
Сообщения: 42
Зарегистрирован: 27 Май 2010, 13:38

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

Сообщение 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)

Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7330
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

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

Сообщение Игорь Столяров »

Дед Пахом писал(а): 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)) - не понимаю как оно с рекурсией их обходит. :(
Если можно объяснить результат - буду благодарен ... :)
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3131
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 10 раз
Поблагодарили: 28 раз
Контактная информация:

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

Сообщение Дед Пахом »

Это потому, что внутренние поля групп принадлежат и внешним группам. Например, 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
С уважением, ДП
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7330
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

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

Сообщение Игорь Столяров »

Спасибо. Понял. Точнее не понял, но буду разбираться ... :)
Еще со времён программирования на Pascal запомнил, что где рекурсия - там всегда что-то не так ... ;)
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 4562
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 6 раз
Поблагодарили: 34 раза

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

Сообщение finsoftrz »

Я рекурсию тоже не воспринимаю. Поэтому обхожусь без нее. Например, можно родителей в кьюшку засовывать по типу стека. Телодвижений больше, зато код мне понятный.
C6/C11, ШВС, tps/btrieve.
Ответить