Форум » [x]Harbour » Функция HB_ValToExp() » Ответить

Функция HB_ValToExp()

Andrey: Давно использую функцию HB_ValToExp(). Но она глючит при показе вложенных массивов. Делаешь ?? HB_ValToExp(aXDim[nI][2]), а выводит фигню: [pre2]__itemSetRef( {{}, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL}, {{{2},{1}},{{3},{1}},{{4},{1}},{{5}, {1}},{{6},{1}},{{7},{1}},{{8},{1}},{{9},{1}},{{10},{1}},{{11},{1}},{{12},{1}},{{13},{1}},{{14},{1}},{{15},{1}},{{16},{1}}} ) [/pre2] Хотя должно вывести значения пустого массива, типа так { {}, {}, {}, .... } Есть ли другая функция в Харборе для вывода вложенных массивов ?

Ответов - 10

gfilatov2002: Andrey пишет: Есть ли другая функция в Харборе для вывода вложенных массивов ? Я нашел только эти две функции в Харборе: hb_ValToExp(<xVal>, [<lRaw>]) ➜ cExp converts a value of any type (including complex types) into a string for serialization. The returned string cExp can be evaluated (f.e. with the macro operator &) to obtain the original value. Optional 2nd parameter <lRaw>, if set to .T., forces all raw serialization format (by default is .F.). hb_ValToStr( <xValue> ) ➜ cText converts a value of any type into a human readable string expression. Complex types are converted to an empty string.

Sergy: hb_ValToExp() применяется для того, чтобы практически любую переменную отобразить в виде строки и понятно для человека. В большинстве случаев, из строки позже можно будет восстановить значение. Исключением являются: а) блоки кода б) указатели Вложенный массив никогда проблемой для hb_ValToExp() не являлся. Вот ее исходный код: https://github.com/vszakats/hb/blob/main/src/rtl/valtoexp.prg В случае сложных переменных вроде объектов и классов - что собственно и видно, исходя из __itemSetRef() - "показывает фигню", значит на вход попадает фигня. Попробуй сделать вместо hb_ValToExp( aXDim[ nI ] [2] ) просто hb_ValToExp(aXDim) и посмотреть, что там.

Andrey: Sergy пишет: Попробуй сделать вместо Не получится. Вот короткий пример: [pre2] aFClr := BLUE aObj := { ; {"oBtn_1" , nRow1, nLeft, nWBtn ,nHBtn,"Список 1" , {"Dogov64x1" ,"Dogov64x2"} , aFClr, CLR_RED_METRO , 1}, ; {"oBtn_2" , nRow2, nLeft, nWBtn ,nHBtn,"Список 2" , {"Abon64x1" ,"Abon64x2"} , aFClr, CLR_BLUE_METRO , 1}, ; {"oBtn_3" , nRow3, nLeft, nWBtn ,nHBtn,"Список 3" , {"Zaivk64x1" ,"Zaivk64x2"} , aFClr, CLR_GREEN_METRO , 1}, ; {"oBtn_4" , nRow1, nLeft, nWBtn ,nHBtn,"Список 4" , {"Oplata64x1","Oplata64x2"}, aFClr, CLR_DARK_PURPLE , 1}, ; {"oBtn_5" , nRow3, nLeft, nWBtn2,nHBtn,"Список 5" , {"Other64x1" ,"Other64x2"} , aFClr, CLR_BRIGHT_BROWN, 1}, ; {"oBtn_6" , nRow2, nLeft, nWBtn ,nHBtn,"Список 6" , {"Calc64x1" ,"Calc64x2"} , aFClr, CLR_YELLOW_METRO, 0}, ; {"oBtn_7" , nRow3, nLeft, nWBtn2,nHBtn,"Список 7" , {"transf64x1","transf64x2"}, aFClr, CLR_DARK_BLUE , 0}, ; {"oBtn_8" , nRow1, nLeft, nWBtn ,nHBtn,"Список 8" , {"Print64x1" ,"Print64x2"} , aFClr, CLR_ORANGE_METRO, 1}, ; {"oBtn_9" , nRow2, nLeft, nWBtn2,nHBtn,"Список 9" , {"Config64x1","Config64x2"}, aFClr, CLR_BLUE_BLUE , 1}, ; {"oBtn_10", nRow2, nLeft, nWBtn2,nHBtn,"Список X" , {"PHelp64x2" ,"PHelp64x3"} , aFClr, CLR_DARK_GREY , 0}, ; {"oBtn_11", nRow3, nLeft, nWBtn ,nHBtn,"Выход" , {"Exit64x1" ,"Exit64x2"} , aFClr, CLR_BRIGHT_RED , 0} ; } ? HB_ValToExp(aObj) [/pre2]


alkresin: Попробуйте hb_jsonEncode()

Andrey: Спасибо, но не совсем то что нужно...

SergKis: Andrey вот так подойдет ? [pre2] IF hb_IsArray(aObj) .and. Len(aObj) > 0 .and. hb_IsArray(aObj[1]) ? aObj ; ?v aObj ; ? ELSE ? HB_ValToExp(aObj) ENDIF для тех, кто не в теме hmg #command ?a [<arr>] => If( <arr> == NIL, , aEval( <arr>, { |xv, ne| _LogFile( ( ne==1 ), ne, xv ), _LogFile() } ) ) #command ?v [<arr>] => If( <arr> == NIL, , aEval( <arr>, { |xv, ne| _LogFile( ( ne==1 ), ne, iif( ValType( xv ) == "A", hb_ValToExp( xv ), xv ) ), _LogFile() } ) ) [/pre2]

SergKis: Andrey пишет не совсем то что нужно... Зря отказался, хороший результат дает [pre2] aFClr := BLUE aObj := { ; {"oBtn_1" , nRow1, nLeft, nWBtn ,nHBtn,"Список 1" , {"Dogov64x1" ,"Dogov64x2"} , aFClr, CLR_RED_METRO , 1}, ; {"oBtn_2" , nRow2, nLeft, nWBtn ,nHBtn,"Список 2" , {"Abon64x1" ,"Abon64x2"} , aFClr, CLR_BLUE_METRO , 1}, ; {"oBtn_3" , nRow3, nLeft, nWBtn ,nHBtn,"Список 3" , {"Zaivk64x1" ,"Zaivk64x2"} , aFClr, CLR_GREEN_METRO , 1}, ; {"oBtn_4" , nRow1, nLeft, nWBtn ,nHBtn,"Список 4" , {"Oplata64x1","Oplata64x2"}, aFClr, CLR_DARK_PURPLE , 1}, ; {"oBtn_5" , nRow3, nLeft, nWBtn2,nHBtn,"Список 5" , {"Other64x1" ,"Other64x2"} , aFClr, CLR_BRIGHT_BROWN, 1}, ; {"oBtn_6" , nRow2, nLeft, nWBtn ,nHBtn,"Список 6" , {"Calc64x1" ,"Calc64x2"} , aFClr, CLR_YELLOW_METRO, 0}, ; {"oBtn_7" , nRow3, nLeft, nWBtn2,nHBtn,"Список 7" , {"transf64x1","transf64x2"}, aFClr, CLR_DARK_BLUE , 0}, ; {"oBtn_8" , nRow1, nLeft, nWBtn ,nHBtn,"Список 8" , {"Print64x1" ,"Print64x2"} , aFClr, CLR_ORANGE_METRO, 1}, ; {"oBtn_9" , nRow2, nLeft, nWBtn2,nHBtn,"Список 9" , {"Config64x1","Config64x2"}, aFClr, CLR_BLUE_BLUE , 1}, ; {"oBtn_10", nRow2, nLeft, nWBtn2,nHBtn,"Список X" , {"PHelp64x2" ,"PHelp64x3"} , aFClr, CLR_DARK_GREY , 0}, ; {"oBtn_11", nRow3, nLeft, nWBtn ,nHBtn,"Выход" , {"Exit64x1" ,"Exit64x2"} , aFClr, CLR_BRIGHT_RED , 0} ; } cBuf := hb_jsonEncode( aObj, .F. ) cBuf := StrTran(cBuf, "[", "{") cBuf := StrTran(cBuf, "]", "}") cBuf := StrTran(cBuf, '},{"', '},'+CRLF+' {"') cBuf := StrTran(cBuf, "}}", "}"+CRLF+"}") ? cBuf ? результат: {{"oBtn_1",1,1,50,20,"Список 1",{"Dogov64x1","Dogov64x2"},{0,0,255},{210,71,38},1}, {"oBtn_2",9,1,50,20,"Список 2",{"Abon64x1","Abon64x2"},{0,0,255},{239,71,38},1}, {"oBtn_3",21,1,50,20,"Список 3",{"Zaivk64x1","Zaivk64x2"},{0,0,255},{255,160,66},1}, {"oBtn_4",1,1,50,20,"Список 4",{"Oplata64x1","Oplata64x2"},{0,0,255},{231,178,30},1}, {"oBtn_5",21,1,70,20,"Список 5",{"Other64x1","Other64x2"},{0,0,255},{251,230,148},1}, {"oBtn_6",9,1,50,20,"Список 6",{"Calc64x1","Calc64x2"},{0,0,255},{251,213,181},0}, {"oBtn_7",21,1,70,20,"Список 7",{"transf64x1","transf64x2"},{0,0,255},{138,85,77},0}, {"oBtn_8",1,1,50,20,"Список 8",{"Print64x1","Print64x2"},{0,0,255},{220,197,193},1}, {"oBtn_9",9,1,70,20,"Список 9",{"Config64x1","Config64x2"},{0,0,255},{128,103,0},1}, {"oBtn_10",9,1,70,20,"Список X",{"PHelp64x2","PHelp64x3"},{0,0,255},{91,91,91},0}, {"oBtn_11",21,1,50,20,"Выход",{"Exit64x1","Exit64x2"},{0,0,255},{225,226,236},0} } [/pre2]

Andrey: SergKis пишет: Зря отказался, хороший результат дает Да, так отлично ! Я не догадался, что так можно сделать.

Sergy: Сделал более простой пример: [pre2]xOther := {100,200,300} aObj := { {1,2,3, {"123","456"}, NIL, 1, "abc", ACLONE(xOther) },; {1,2,3, {"123","456"}, NIL, 1, "abc", ACLONE(xOther) } } ? hb_ValToExp( aObj )[/pre2] Соотв. это подтверждает, что массивы любой вложенности не являются проблемой для hb_ValToExp(). Если же массив содержит ссылки на другие объекты/массивы - начинается формирование "сложного" содержимого через __itemSetRef. Чтобы убедиться в этом - достаточно заменить ACLONE на прямые ссылки на xOther. Это и понятно, тк одна из ключевых фишек hb_ValToExp() - обратное воссоздание всего массива целиком. Чего в случае с использованием hb_jsonEncode() не получится, тк. все ссылки на, к примеру, aFClr, будут заменены на значения.

Andrey: Сделал для себя так (может кому пригодиться): [pre2]? "aObj= " + Hmg_Array(aObj) ...... FUNCTION Hmg_Array(a) LOCAL i, cStr := "" IF !hb_IsArray(a) RETURN " This is not an array !" ENDIF IF Len(a) > 0 .and. hb_IsArray(a[1]) cStr += "{ " + CRLF FOR i := 1 TO LEN(a) cStr += SPACE(13) cStr += HB_ValToExp(a) + IIF( i==LEN(a), CRLF, "," + CRLF) NEXT cStr += SPACE(11) + "}" ELSE cStr += HB_ValToExp(a) ENDIF cStr := "ARRAY[" + hb_NToS( Len(a) ) + "] = " + cStr RETURN cStr [/pre2] Сергей предлагает такой вариант: [pre2]s := "" ; hb_ForNext( 1, Len( a ), {|i| s += hb_valtoexp(a[ i ])+chr(9) }) ; ? "ARRAY["+hb_ntos(Len(a))+"]=" + s [/pre2] Я его немного подправил:[pre2] s := "" hb_ForNext( 1, Len( a ), {|i| s += IIF(i==1,"",SPACE(11)) + hb_valtoexp(a[ i ]) + CRLF }) ? "ARRAY["+hb_ntos(Len(a))+"]= " + s ....... Результат: ARRAY[11]= {"oBtn_1", 10, 10, 10, 10, "Список 1", {"Dogov64x1", "Dogov64x2"}, {0, 0, 255}, {189, 30, 73}, 1} {"oBtn_2", 10, 10, 10, 10, "Список 2", {"Abon64x1", "Abon64x2"}, {0, 0, 255}, {40, 122, 237}, 1} {"oBtn_3", 10, 10, 10, 10, "Список 3", {"Zaivk64x1", "Zaivk64x2"}, {0, 0, 255}, {0, 145, 0}, 1} {"oBtn_4", 10, 10, 10, 10, "Список 4", {"Oplata64x1", "Oplata64x2"}, {0, 0, 255}, {82, 0, 141}, 1} {"oBtn_5", 10, 10, 10, 10, "Список 5", {"Other64x1", "Other64x2"}, {0, 0, 255}, {138, 85, 77}, 1} {"oBtn_6", 10, 10, 10, 10, "Список 6", {"Calc64x1", "Calc64x2"}, {0, 0, 255}, {231, 178, 30}, 0} {"oBtn_7", 10, 10, 10, 10, "Список 7", {"transf64x1", "transf64x2"}, {0, 0, 255}, {0, 155, 173}, 0} {"oBtn_8", 10, 10, 10, 10, "Список 8", {"Print64x1", "Print64x2"}, {0, 0, 255}, {210, 71, 38}, 1} {"oBtn_9", 10, 10, 10, 10, "Список 9", {"Config64x1", "Config64x2"}, {0, 0, 255}, {9, 77, 181}, 1} {"oBtn_10", 10, 10, 10, 10, "Список X", {"PHelp64x2", "PHelp64x3"}, {0, 0, 255}, {91, 91, 91}, 0} {"oBtn_11", 10, 10, 10, 10, "Выход", {"Exit64x1", "Exit64x2"}, {0, 0, 255}, {254, 73, 83}, 0}[/pre2]



полная версия страницы