Jump to content

qsek

Active Members
  • Posts

    264
  • Joined

  • Last visited

  • Days Won

    1

qsek last won the day on April 23 2012

qsek had the most liked content!

About qsek

  • Birthday 11/13/1979

Profile Information

  • Location
    Germany

Recent Profile Visitors

804 profile views

qsek's Achievements

Universalist

Universalist (6/7)

20

Reputation

  1. @LWC I just discovered that the Json UDF from @Ward works with the Scripting Dictionary and added Dot Notation a while ago, including array management. I did some tests and you absolutely can use x and json function interchangeably. Is this a solution for you usecase? #include "Json.au3" #include <AssoArrays.au3> $x = $_xHashCollection x("section","key1") Json_Put($x, ".hello", "world") Json_Put($x, ".foo.bar", "foobar") x_del("foo.bar") x_del("foo") x("main","") ; mixing x with json Json_Put($x, ".main.test[0]", "1111") ; manual adding of elements Json_Put($x, ".main.test[1]", "2222") ; manual adding of elements $a = x("main.test") ; adding with autoit functions by unpacking/packing _ArrayAdd($a, "3333") x("main.test",$a) Json_Put($x, ".main.test["&UBound(x("main.test"))&"]", "1234") ; adding elements at end without unpacking ; iteration For $val In x("main.test") ConsoleWrite("$val: " & $val & @CRLF) Next ; iteration with index For $i = 0 To UBound(x("main.test"))-1 ConsoleWrite(x("main.test")[$i] & @CRLF) Next ; writing without unpacking Json_Put($x, ".main.test[1]", "0000") ; reading without unpacking $val = Json_Get($x, ".main.test[1]") ConsoleWrite("Json_Get: " & $val & @CRLF) x_display() Exit
  2. Im not sure what you mean by "crashing the program" with returning an error from the function. I think this should be the intended return. The Loop iterates the $sectionArray that is either: generated from IniReadSectionNames, which shuld not generate an error because the sections were just read and should exist. And even if not (due to external changing) the user should be informed of that through an error. or is filled with only this one section the user specifically requested in the optional $mySection parameter. In which case the user should be informed if that section does not exist by an error, just like IniReadSectionNames does. If, in your case, he gets an empty section, where should he know, that it is really empty or if it doesnt exist? An error return is the apropriate way imho. I intentionally wanted to hide the "extension mangement" from the user so it is more clear, that you should use the same string for the root item as well as the name part of the ini file. But as i was cheking your suggestion, i came to ask myself "Why not both?". If you dont care about the extension, you just use Func _ReadAssocFromIni() or _ReadAssocFromIni("myconfig") like before. In this case ".ini" will be added. If you specify an extension, it will use this to load the file but only the name part for the AssoArray key will be used: Func _ReadAssocFromIni($myIni = 'config.ini', $mySection = '', $sSep = "|") If Not StringInStr($myIni,".") Then $myIni &= ".ini" Local $sIni = StringLeft($myIni,StringInStr($myIni,".")-1) The ReadAssocFrom and WriteAssocToIni functions are a subset of The AssoArray UDF. I think most users will work with this UDF mainly to be able to use values in a nested, treepath-like fashion within a script. My goal was to provide a way to store a subset of these variables in ini form if you were using the UDF anyway (this is mainly my usecase, too). So in order to not not conflict with my existing keys in the main dictionary, it is sensible to keep the extra "config" key for your ini management and be able to store other data in the main dictionary without it being written to the config unintentionally. Its also more clear if you access a config value with x() to have the config name within the key string so you know it is a config value that will be stored later eventually. If this would be a separate AssocIni UDF where the user was not intended to use the ini dictionary for something else, this would be more logical. But then, some more things would have to change. Anyway thanks for your suggestions. You are right, dictionarys were not designed like that. Either you solve this by using numbered sub keys and write additional x functions for adding, deleting, and iterating already existing subkeys to be able to use it more "array-like". Or you create an array to store subkeys, and store this array as value of your key. This would enable you to use existing autoit functions for array management, but you would have to unpack/pack the array everytime you want to read/write any values. If you are really fancy, you could incorporate arrayidexes into the dot annotation, so you can use it like x("section.key[3].subkey"), x("section.key[-3]"), x("section.key[+]","value") etc.
  3. Just wanted to share a quick proof of concept with some performance testing. GraphGDIPlus lacked performance and interactivity for me so i searched new way to generate graphs. Potential is huge especially when you consider using d3.js instead of chart.js #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <Array.au3> #include <File.au3> #include <Date.au3> #include <IE.au3> Opt("GuiOnEventMode", 1) $oIE = ObjCreate("Shell.Explorer.2") $Form1 = GUICreate("Embedded Web control Test", 1140, 380, _ (@DesktopWidth - 1140) / 2, (@DesktopHeight - 380) / 2, _ $WS_OVERLAPPEDWINDOW + $WS_CLIPSIBLINGS + $WS_CLIPCHILDREN) GUICtrlCreateObj($oIE, 10, 10, 1120, 360) GUICtrlSetResizing ( -1, 1 ) GUISetOnEvent(-3, "_MyExit", $Form1) GUISetState() Func _MyExit() Exit EndFunc ConsoleWrite("generating dataset..." & @CRLF) ; generate a 5k line dataset ; string $datastr = "" For $i = 0 To 2000 $date = _DateAdd("n", $i, "2021/02/14 00:00:00") $datastr &= $date&","&Random(1,500,1)& @CRLF next $datastr = StringTrimRight($datastr, 2) ; array Dim $dataarr[0][2] _ArrayAdd ( $dataarr, $datastr, 0, ",", @CRLF) ConsoleWrite("finished." & @CRLF& @CRLF) $oIE.navigate( "about:blank") $html = "" Sethtml() _IEDocWriteHTML($oIE, $html) _IEAction ( $oIE, "refresh" ) _IELoadWait($oIE) ;~ ; watch your variable/function case with that notation! $ohJS = $oIE.document.parentwindow.JSglobal ;~ ; need to eval [0], javascript arrays are not compatible with autoit arrays or object collections $dset = $ohJS.eval("myChart.data.datasets[0]") $dset.label = "Test1: init dataset with jsvariable.push()" $ohJS.myChart.update() ConsoleWrite("Test1: init dataset with jsvariable.push()"& @CRLF) $ti = TimerInit() ; Test1 $glabels = $ohJS.myChart.data.labels For $i = 0 To UBound($dataarr)-1 If Mod($i,1000) = 0 then ConsoleWrite($i & @CRLF) $glabels.push($dataarr[$i][0]) $dset.data.push($dataarr[$i][1]) next $ohJS.myChart.update() ConsoleWrite("Test1: "&Round(TimerDiff($ti),1)&" ms"& @CRLF) Sleep(2000) $ohJS.GraphClearData() Sleep(1000) ConsoleWrite("Test2: init dataset with passing datastring to js function"& @CRLF) $ti = TimerInit() ; Test2 $ohJS.InitGraphWithData($datastr) $ohJS.myChart.update() ConsoleWrite("Test2: "&Round(TimerDiff($ti),1)&" ms"& @CRLF) Sleep(2000) $ohJS.GraphClearData() $dset.label = "Test3: add data with jsvariable.push()" $ohJS.myChart.update() ConsoleWrite("Test3: add data with jsvariable.push()"& @CRLF) $ti = TimerInit() ; Test3 $glabels = $ohJS.myChart.data.labels For $i = 0 To 500 If Mod($i,100) = 0 then $dset.label = "Test3: add data with jsvariable.push() ("&$i&"/500)" $date = _DateAdd("n", $i, "2021/02/14 00:00:00") $glabels.push($date) $dset.data.push(Random(1,500+$i,1)) $ohJS.myChart.update() Next ConsoleWrite("Test3: "&Round(TimerDiff($ti),1)&" ms"& @CRLF) $ohJS.GraphClearData() ConsoleWrite("Test4: add data with passing datastring to js function" & @CRLF) $ti = TimerInit() ; Test4 For $i = 0 To 500 If Mod($i,100) = 0 then $dset.label = "Test4: add data with passing datastring to js function ("&$i&"/500)" $date = _DateAdd("n", $i, "2021/02/14 00:00:00") $ohJS.GraphAddData($date&","&Random(1,500+$i,1)) If Mod($i,100) = 0 then $dset.label = "Test4: add data with passing datastring to js function ("&$i&"/500)" Next ConsoleWrite("Test4: "&Round(TimerDiff($ti),1)&" ms"& @CRLF) ConsoleWrite("testing ended" & @CRLF) $dset.label = "You can click on points" $ohJS.myChart.update() While 1 For $i = 0 To $ohJS.clickedPoints.length -1 $label = $ohJS.eval("myChart.data.labels[clickedPoints["&$i&"]._index].format('YYYY/MM/DD hh:mm:ss');") $value = $ohJS.eval("myChart.data.datasets[clickedPoints["&$i&"]._datasetIndex].data[clickedPoints["&$i&"]._index];") ConsoleWrite("You clicked at " & $label & ", "&$value & @CRLF) Next $ohJS.clickedPoints = "" Sleep(10) WEnd exit Func Sethtml() $html = "<!DOCTYPE html>" & @CRLF & _ "<html lang='en'>" & @CRLF & _ "" & @CRLF & _ "<head>" & @CRLF & _ " <meta charset='UTF-8'>" & @CRLF & _ " <meta http-equiv='X-UA-Compatible' content='IE=edge' >" & @CRLF & _ " <script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'></script>" & @CRLF & _ " <script src='https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js'></script>" & @CRLF & _ " <script src='https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js'></script>" & @CRLF & _ " <title>My Chart</title>" & @CRLF & _ "</head>" & @CRLF & _ "" & @CRLF & _ "<body>" & @CRLF & _ " <div class='container'> <canvas id='myChart' width='100' height='30'></canvas></div>" & @CRLF & _ "" & @CRLF & _ " <script>" & @CRLF & _ " var JSglobal = (1,eval)('this');" & @CRLF & _ " var au3data = ['test','123'];" & @CRLF & _ " var clickedPoints = '';" & @CRLF & _ " Chart.defaults.global.animation.duration = 0;" & @CRLF & _ " Chart.defaults.global.hover.animationDuration = 0;" & @CRLF & _ " Chart.defaults.global.animation.easing = 'linear';" & @CRLF & _ " Chart.defaults.global.elements.line.tension = 0;" & @CRLF & _ " Chart.defaults.global.elements.line.backgroundColor = 'rgba(255, 99, 132, 0.2)';" & @CRLF & _ " Chart.defaults.global.elements.line.borderColor = 'rgba(255, 99, 132, 1)';" & @CRLF & _ "" & @CRLF & _ " Chart.defaults.global.responsiveAnimationDuration = 0;" & @CRLF & _ " //Chart.defaults.line.showLines = false;" & @CRLF & _ " Chart.defaults.line.spanGaps = false;" & @CRLF & _ "" & @CRLF & _ " function GraphClearData() {" & @CRLF & _ " myChart.data.datasets[0].data = [];" & @CRLF & _ " myChart.data.labels = [];" & @CRLF & _ " myChart.update(0);" & @CRLF & _ " }" & @CRLF & _ "" & @CRLF & _ " function InitGraphWithData(datastring, rowdelim, coldelim) {" & @CRLF & _ " rowdelim = typeof rowdelim !== 'undefined' ? rowdelim : '\n';" & @CRLF & _ " coldelim = typeof coldelim !== 'undefined' ? coldelim : ',';" & @CRLF & _ " GraphClearData();" & @CRLF & _ "" & @CRLF & _ " var allLinesArray = datastring.split('\n');" & @CRLF & _ " if (allLinesArray.length > 0) {" & @CRLF & _ " for (var i = 0; i < allLinesArray.length; i++) {" & @CRLF & _ " var rowData = allLinesArray[i].split(',');" & @CRLF & _ " if (rowData[0] != '') {" & @CRLF & _ " myChart.data.labels.push(moment(rowData[0], 'YYYY/MM/DD hh:mm:ss'));" & @CRLF & _ " myChart.data.datasets[0].data.push(rowData[1]);" & @CRLF & _ " }" & @CRLF & _ " }" & @CRLF & _ " }" & @CRLF & _ " myChart.update();" & @CRLF & _ " }" & @CRLF & _ "" & @CRLF & _ "" & @CRLF & _ " function GraphAddData(datastring, rowdelim, coldelim) {" & @CRLF & _ " rowdelim = typeof rowdelim !== 'undefined' ? rowdelim : '\n';" & @CRLF & _ " coldelim = typeof coldelim !== 'undefined' ? coldelim : ',';" & @CRLF & _ "" & @CRLF & _ " var allLinesArray = datastring.split('\n');" & @CRLF & _ " if (allLinesArray.length > 0) {" & @CRLF & _ " for (var i = 0; i < allLinesArray.length; i++) {" & @CRLF & _ " var rowData = allLinesArray[i].split(',');" & @CRLF & _ " if (rowData[0] != '') {" & @CRLF & _ " //alert('adding '+rowData[0]+', '+rowData[1]);" & @CRLF & _ " myChart.data.labels.push(moment(rowData[0], 'YYYY/MM/DD hh:mm:ss'));" & @CRLF & _ " myChart.data.datasets[0].data.push(rowData[1]);" & @CRLF & _ " }" & @CRLF & _ " }" & @CRLF & _ " }" & @CRLF & _ " myChart.update();" & @CRLF & _ " }" & @CRLF & _ "" & @CRLF & _ " var ctx = document.getElementById('myChart').getContext('2d');" & @CRLF & _ "" & @CRLF & _ " document.getElementById('myChart').onclick = function(evt) {" & @CRLF & _ " clickedPoints = myChart.getElementsAtEvent(evt);" & @CRLF & _ " };" & @CRLF & _ "" & @CRLF & _ " var myChart = new Chart(ctx, {" & @CRLF & _ " type: 'line'," & @CRLF & _ " data: {" & @CRLF & _ " datasets: [{" & @CRLF & _ " label: ''," & @CRLF & _ " }]" & @CRLF & _ " }," & @CRLF & _ " options: {" & @CRLF & _ " responsive: 'true'," & @CRLF & _ " scales: {" & @CRLF & _ " xAxes: [{" & @CRLF & _ " type: 'time'," & @CRLF & _ " time: {" & @CRLF & _ " displayFormats: {" & @CRLF & _ " minute: 'DD.MMM H:m'" & @CRLF & _ " }" & @CRLF & _ " }," & @CRLF & _ " distribution: 'linear'," & @CRLF & _ " ticks: {" & @CRLF & _ " source: 'auto'" & @CRLF & _ " }," & @CRLF & _ " bounds: 'bounds'" & @CRLF & _ " }]" & @CRLF & _ " }" & @CRLF & _ " }" & @CRLF & _ " });" & @CRLF & _ "" & @CRLF & _ " myChart.update();" & @CRLF & _ "" & @CRLF & _ " <!-- setInterval(function() { -->" & @CRLF & _ " <!-- updateChart() -->" & @CRLF & _ " <!-- }, 5000); -->" & @CRLF & _ " </script>" & @CRLF & _ "</body>" & @CRLF & _ "" & @CRLF & _ "</html>" & @CRLF EndFunc
  4. @jchd good suggestion, updated in my post.
  5. Its 2020 and i still use this very useful UDF. I've come to expand the x_display function (originally only for Dictionarys and Arrays) to also handle Maps and MultiDimensional Arrays with > 2 Dimensions (There was a bug with the original code which would not display those correctly) And the best is that you can nest and mix any combination of Dicts, MultiDim Arrays and Maps. Here is an Example: Dim $t1[2] = ["A","B"] Dim $m[] Dim $subm[] $m[12345678] = "This" $m["12345678"] = "That" $m.maptest1 = $subm $m.maptest1.submaptest1 = 3.141 $m["maptest1"][111] = "string" $m.maptest1.submaptest3 = $t1 Dim $t2[3][2] = [[1,2],[3,$m],[5,6]] $x = ObjCreate("Scripting.Dictionary") $x.add("main", ObjCreate("Scripting.Dictionary")) $x.Item("main").add( "test1", "hello") $x.Item("main").add( "test2", $t2) $x.add("sub", ObjCreate("Scripting.Dictionary")) $x.Item("sub").add( "sub1", "world") $x.Item("sub").add( "sub2", 3.141) Dim $t[2][3][4] = [[[1,2,3,4],[4,5,6,7],[7,$x,9,0]],[[11,22,33,44],[44,55,66,77],[77,88,99,00]]] Dim $p[4][2][3] = _ [ _ [ _ ["272,00,47","01,47,37","325,56,50"], _ ["325,57,11","04,14,11","04,01,10"] _ ], _ [ _ ["272,00,40","01,33,53","01,41,00"], _ ["325,56,50","04,01,10","272,00,40"] _ ], _ [ _ [$t,"01,41,00","01,47,37"], _ ["323,50,01","04,04,15","272,00,47"] _ ], _ [ _ ["272,00,40","01,41,00","01,47,37"], _ ["323,50,01","325,56,50","01,33,53"] _ ] _ ] ;~ ConsoleWrite( _VarDump($p)& @CRLF) x_display($p, 0, "$p") Exit ; #FUNCTION# ==================================================================================================================== ; Name...........: x_display ; Description ...: Writes the contents of an Associative Array to the Console ; Syntax.........: x_display( $key = '' , $MultiArr3DView = False, $sName = '' ) ; Parameters ....: $sKey - the value to display. If empty, outputs the content of $_xHashCollection ; $MultiArr3DView - display multidimensional arrays in a tiled manner ; $sName - prefix output with user string (for example the varibale name) ; Examples: ; x_display() displays everything ; x_display( 'foo' ) displays the contents of foo ; Authors .......: OHB <me at orangehairedboy dot com>, qsek ; =============================================================================================================================== Func x_display( $key = '' , $MultiArr3DView = False, $sName = '') Local $text If Not IsObj($key) And Not isMap($key) And Not isArray($key)Then $text = $key $text &= StringTrimRight( _x_display($key ,$sName , ' ', 1, '', $MultiArr3DView ) , 2 ) ConsoleWrite($text & @LF) EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name...........: _x_display ; Description ...: Itterates through a map/Dictionary/array and builds output for x_display ; Authors .......: OHB <me at orangehairedboy dot com>, qsek ; =============================================================================================================================== Func _x_display( $item , $sName = "", $tab = '', $level = 1, $sArrSubscr = "", $MultiArr3DView = False) Static $_MultiArr3DView = ($MultiArr3DView+0 = True) Local $text If $sName <> "" Then $text &= $sName&":" If IsMap( $item ) Then If $level = 1 Then $text &= ' => '& "Map" $text &= ' {' & @CRLF $aMapKeys = MapKeys($item) For $i In $aMapKeys $save = $item[$i] $a = IsString($i) ? "'" : '' $text &= $tab & "["&$a & $i & $a&"]" & _x_display( $item[$i] ,"" , $tab&" ", IsMap($save) ? $level+1 : 1) Next $text &= StringTrimRight($tab, 2) & '}' ElseIf IsObj( $item ) Then If $level = 1 Then $text = ' => '& ObjName($item, 1) $text &= ' (' & @CRLF For $i In $item $value = $item.item($i) $a = IsString($i) ? "'" : '' $text &= $tab &"["&$a & $i &$a&"]" & _x_display( $value , "", $tab&" " , IsObj($value) ? $level+1 : 1 ) Next $text &= StringTrimRight($tab, 2) & ')' ElseIf IsArray( $item ) Then If $level = 1 Then $text &= ' => '& "Array" $dimensions = UBound( $item , 0 ) For $dimension = 1 To $dimensions $size = UBound( $item , $dimension ) $text &= "[" & $size & "]" Next $text &= " (" & @CRLF $sArrSubscr = ""; clear from possible "sub" flag EndIf ;Loop through all elements within the current dimension For $i = 0 to Ubound($item, $level)-1 If $level < Ubound($item, 0) Then ; we need to go deeper, pass on subscription string. Also pass original array so we end up here again $text &= _x_display( $item , "" ,$tab, $level+1, $sArrSubscr&"[" & $i & "]") Else ; we reached the last dimension, Execute the array subscription string If $_MultiArr3DView And $i > 0 Then If UBound( $item , 0 ) > 1 Then $text &= " , " ; Separation between first Dimension items on one line Else $text &= @CRLF&$tab ; If ony 1 dim array -> put every item on new line EndIf Else $text &= $tab EndIf $value = Execute( "$item" & $sArrSubscr&"[" & $i & "]") $text &= $sArrSubscr&"[" & $i & "]" & _x_display( $value , "" , $tab&" ", 1, "sub") If $_MultiArr3DView And StringRight($text, 2) = @CRLF Then $text &= $tab EndIf Next If $level = 1 Then If $_MultiArr3DView and UBound( $item , 0 ) = 1 Then $text &= @CRLF $text &= StringTrimRight($tab, 2) & ')' If Not $_MultiArr3DView Then $text &= @CRLF EndIf If Not $_MultiArr3DView Then Return $text Else $p = IsString($item) ? '"' : '' ; Put Strings in "" $text = ' = '&$p&$item&$p If $_MultiArr3DView And $sArrSubscr = "sub" Then Return $text EndIf $text &= @CRLF Return $text EndFunc Output: $p: => Array[4][2][3] ( [0][0][0] = "272,00,47" [0][0][1] = "01,47,37" [0][0][2] = "325,56,50" [0][1][0] = "325,57,11" [0][1][1] = "04,14,11" [0][1][2] = "04,01,10" [1][0][0] = "272,00,40" [1][0][1] = "01,33,53" [1][0][2] = "01,41,00" [1][1][0] = "325,56,50" [1][1][1] = "04,01,10" [1][1][2] = "272,00,40" [2][0][0] => Array[2][3][4] ( [0][0][0] = 1 [0][0][1] = 2 [0][0][2] = 3 [0][0][3] = 4 [0][1][0] = 4 [0][1][1] = 5 [0][1][2] = 6 [0][1][3] = 7 [0][2][0] = 7 [0][2][1] => Dictionary ( ['main'] ( ['test1'] = "hello" ['test2'] => Array[3][2] ( [0][0] = 1 [0][1] = 2 [1][0] = 3 [1][1] => Map { [12345678] = "This" ['12345678'] = "That" ['maptest1'] { ['submaptest1'] = 3.141 [111] = "string" ['submaptest3'] => Array[2] ( [0] = "A" [1] = "B" ) } } [2][0] = 5 [2][1] = 6 ) ) ['sub'] ( ['sub1'] = "world" ['sub2'] = 3.141 ) ) [0][2][2] = 9 [0][2][3] = 0 [1][0][0] = 11 [1][0][1] = 22 [1][0][2] = 33 [1][0][3] = 44 [1][1][0] = 44 [1][1][1] = 55 [1][1][2] = 66 [1][1][3] = 77 [1][2][0] = 77 [1][2][1] = 88 [1][2][2] = 99 [1][2][3] = 0 ) [2][0][1] = "01,41,00" [2][0][2] = "01,47,37" [2][1][0] = "323,50,01" [2][1][1] = "04,04,15" [2][1][2] = "272,00,47" [3][0][0] = "272,00,40" [3][0][1] = "01,41,00" [3][0][2] = "01,47,37" [3][1][0] = "323,50,01" [3][1][1] = "325,56,50" [3][1][2] = "01,33,53" ) Same Output but with Option $MultiArr3DView = True: $p: => Array[4][2][3] ( [0][0][0] = "272,00,47" , [0][0][1] = "01,47,37" , [0][0][2] = "325,56,50" [0][1][0] = "325,57,11" , [0][1][1] = "04,14,11" , [0][1][2] = "04,01,10" [1][0][0] = "272,00,40" , [1][0][1] = "01,33,53" , [1][0][2] = "01,41,00" [1][1][0] = "325,56,50" , [1][1][1] = "04,01,10" , [1][1][2] = "272,00,40" [2][0][0] => Array[2][3][4] ( [0][0][0] = 1 , [0][0][1] = 2 , [0][0][2] = 3 , [0][0][3] = 4 [0][1][0] = 4 , [0][1][1] = 5 , [0][1][2] = 6 , [0][1][3] = 7 [0][2][0] = 7 , [0][2][1] => Dictionary ( ['main'] ( ['test1'] = "hello" ['test2'] => Array[3][2] ( [0][0] = 1 , [0][1] = 2 [1][0] = 3 , [1][1] => Map { [12345678] = "This" ['12345678'] = "That" ['maptest1'] { ['submaptest1'] = 3.141 [111] = "string" ['submaptest3'] => Array[2] ( [0] = "A" [1] = "B" ) } } [2][0] = 5 , [2][1] = 6 ) ) ['sub'] ( ['sub1'] = "world" ['sub2'] = 3.141 ) ) , [0][2][2] = 9 , [0][2][3] = 0 [1][0][0] = 11 , [1][0][1] = 22 , [1][0][2] = 33 , [1][0][3] = 44 [1][1][0] = 44 , [1][1][1] = 55 , [1][1][2] = 66 , [1][1][3] = 77 [1][2][0] = 77 , [1][2][1] = 88 , [1][2][2] = 99 , [1][2][3] = 0 ) , [2][0][1] = "01,41,00" , [2][0][2] = "01,47,37" [2][1][0] = "323,50,01" , [2][1][1] = "04,04,15" , [2][1][2] = "272,00,47" [3][0][0] = "272,00,40" , [3][0][1] = "01,41,00" , [3][0][2] = "01,47,37" [3][1][0] = "323,50,01" , [3][1][1] = "325,56,50" , [3][1][2] = "01,33,53" ) If you need an even more verbose Output with Types and Ubounds there is also this excellent VarDump UDF from @jchd
  6. Also i would add that this command line approach is quite slow. I got 500 ms+ for each query. Can be very slow if you have loops with queries. Isn't there a COM or DLL version?
  7. In jqInit() the code for searching the jq-winXX.exe files is not language proof. You use the "where" command to search for the files in the @ScriptDir $iPid = Run(StringFormat("where jq-win%s.exe", $s32or64), @ScriptDir, @SW_HIDE, $STDERR_MERGED) But the return of where.exe can be localized depending of OS language. for example in my german OS, jqInit() does not give an error although no file has been found: $sExePath = _jqInit() If @error Then ConsoleWrite(StringFormat("ERROR: Unable to initialize jq - @error = %s", @error) & @CRLF) Exit -1 EndIf ConsoleWrite(StringFormat("jq Path = %s", $sExePath) & @CRLF) ConsoleWrite(StringFormat("jq UDF Version = %s", _jqUdfVersion()) & @CRLF) ConsoleWrite(StringFormat("jq Version = %s", _jqVersion()) & @CRLF) jq_debug_log.txt: I suggest you use a simple FileExists if no Path was supplied: ;If exe path was supplied If StringStripWS($sExePath, $STR_STRIPLEADING + $STR_STRIPTRAILING ) <> "" Then If $__jq_gbDebugging Then __jqWriteLogLine(StringFormat("Exe path supplied to _jqInit = %s", $sExePath)) ;If the file does not exist If Not FileExists($sExePath) Then Return SetError(2, 0, "") ;Set global var and return $__jq_gsJqExeFilePath = $sExePath Else If $__jq_gbDebugging Then __jqWriteLogLine("Searching for jq executable") $sExePath = @ScriptDir&"\jq-win"&$s32or64&".exe" If Not FileExists($sExePath) Then If $__jq_gbDebugging Then __jqWriteLogLine("jq executable not found") Return SetError(2, 0, "") EndIf If $__jq_gbDebugging Then __jqWriteLogLine(StringFormat("jq executable found = %s", $sExePath)) $__jq_gsJqExeFilePath = $sExePath ;~ not OS language proof ;~ ;Search for exe ;~ $iPid = Run(StringFormat("where jq-win%s.exe", $s32or64), @ScriptDir, @SW_HIDE, $STDERR_MERGED) ;~ If @error Then Return SetError(3, 0, "") ;~ ;Wait for command to close and get output ;~ ProcessWaitClose($iPid, 10) ;~ $sCmdOutput = StdoutRead($iPid) ;~ ConsoleWrite($sCmdOutput & @CRLF) ;~ ;If exe not found ;~ If StringInStr($sCmdOutput, "Could not find") Then ;~ If $__jq_gbDebugging Then __jqWriteLogLine("jq executable not found") ;~ Return SetError(1, 0, "") ;~ EndIf ;~ ;Parse first line from output ;~ $aResult = StringRegExp($sCmdOutput, ".*", 3) ;~ If Not IsArray($aResult) Then Return SetError(1, 0, "") ;~ ;Set global var ;~ If $__jq_gbDebugging Then __jqWriteLogLine(StringFormat("jq executable found = %s", $aResult[0])) ;~ $__jq_gsJqExeFilePath = $aResult[0] EndIf Is there a reason you do the whole Run/where/StdoutRead block when no Path was supplied?
  8. I know this is 2 years old but maybe this can still help you. Global $OneNote = ObjCreate("OneNote.Application.12") $string = "" $OneNote.GetHierarchy("", 3, $string); ConsoleWrite($string & @CRLF) You dont need AutoitObject UDF. However this works only for OneNote 2010. It selects the Microsoft OneNote 12.0 Type Lib specifically, which functions (like GetHierarchy) should work like intended (for OneNote 2010) But im having a really hard time to get it working in a system with OneNote 2016 installed. The Object Is created, but calling functions yields "The requested action with this object has failed." Both the 12.0 and 15.0 Type Libs are present. Maybe you have any clue whats the problem? What OneNote version are you working on?
  9. After some trying i found a workaround: Dim $player[] Dim $sub[] $player.test1 = 1 $player.test2 = $sub $player.test2.child1 = "org" $player.test2.childext = $sub $player.test2.childext.child1 = "org2" $player.a = $player ; make a temporary copy of the whole map inside an unused key of the map to be copied. ; This also forces the submaps to get their unique copies and all references to 'root' $player are cut. $playerold = $player.a ; So $playerold will recieve a independent copy of $player MapRemove($player, "a") ; Temporary copy not needed any more ConsoleWrite("player.test2.child1 : "& $player.test2.child1 & @CRLF); original nested value in $player $playerold.test2.child1 = "changed" ; edit a nested value in $playerold ConsoleWrite("player.test2.child1 : "& $player.test2.child1 & @CRLF) ; original nested value in $player changed ConsoleWrite("---------------------" & @CRLF) ConsoleWrite("player.test2.childext.child1 : "& $player.test2.childext.child1 & @CRLF); original level2 nested value in $player $playerold.test2.childext.child1 = "changed2" ; edit a level2 nested value in $playerold ConsoleWrite("player.test2.child1 : "& $player.test2.child1 & @CRLF); original level1 nested value in $player stayed the same ConsoleWrite("player.test2.childext.child1 : "& $player.test2.childext.child1 & @CRLF); original level2 nested value in $player changed
  10. @spudw2k not really the same. As expected because it is an object that will execute Methods on its own and give the data to the parent. That is also why you cannot add the 2nd level "child1" in $oPlayer.Item("test2").Item("childext").Add("child1", "org2") Because you already added it one level higher before to the same $oSub: $oPlayer.Item("test2").Add("child1", "org") Essentially what you are doing is $oPlayer.Item("test2").{ $oSub.Add("child1", "org") } $oPlayer.Item("test2").Item("childext").{ $oSub.Add("child1", "org") } Also your $oSub on its own fills with items as you use it with $oPlayer as parent. My Map $sub on the other hand will not fill with items. It is empty if you look at it after filling it with data with $player as parent. So internally it will create a new Map everytime you assign a submap like so. $player.test2 = $sub and also when creating a second version on a deeper level in one parentmap. I think this is intended as you dont have a ObjCreate with Maps. However if the whole map is copied, it creates references of the individual submaps in the copied one, which i think is not intended.
  11. Im not sure if this is intended but normally Autoit variables are always passed as copies (except objects i think). But below i observed an unconsistency when copying maps with nested maps inside. Issue: If you create a nested map1 and copy it to a new map2, changing a nested value in map2 will also change the nested value in map1 Dim $player[] Dim $sub[] $player.test1 = 1 $player.test2 = $sub $player.test2.child1 = "org" $player.test2.childext = $sub $player.test2.childext.child1 = "org2" $playerold = $player ; make a copy of the whole map ConsoleWrite("player.test2.child1 : "& $player.test2.child1 & @CRLF); original nested value in $player $playerold.test2.child1 = "changed" ; edit a nested value in $playerold ConsoleWrite("player.test2.child1 : "& $player.test2.child1 & @CRLF) ; original nested value in $player changed ConsoleWrite("---------------------" & @CRLF) ConsoleWrite("player.test2.childext.child1 : "& $player.test2.childext.child1 & @CRLF); original level2 nested value in $player $playerold.test2.childext.child1 = "changed2" ; edit a level2 nested value in $playerold ConsoleWrite("player.test2.child1 : "& $player.test2.child1 & @CRLF); original level1 nested value in $player stayed the same ConsoleWrite("player.test2.childext.child1 : "& $player.test2.childext.child1 & @CRLF); original level2 nested value in $player changed
  12. Can somebody try to reproduce this bug? It would be helpful to know if this issue appeares on other environments too. Issue: Sometimes values of certain keys will return empty even if expicitly assigned a value before. Conditions: Map is bigger than ~50 key/values pairs value is being worked with in a Function where a loop is iterating through the Map before retrieving the value there is a isMap/MapKeys/MapAppend/MapRemove check on the Map value. Dim $mMap[] ; Generate random key strings For $i = 0 To 100 $RndKey = "" For $i2 = 0 To 4 $RndKey &= Chr(Random(65,90,1)) Next $mMap[$RndKey] = 999 next ConsoleWrite("-----------1-------------" & @CRLF); Unpredictable blank values MapDisplay1($mMap) ConsoleWrite("-----------2-------------" & @CRLF); ByRef always works MapDisplay2($mMap) ConsoleWrite("-----------3-------------" & @CRLF); not in a function always works For $i In MapKeys($mMap) isMap($mMap[$i]) ConsoleWrite($i&": "&$mMap[$i]&@CRLF) Next Func MapDisplay1( $m_Map ) For $i In MapKeys($m_Map) isMap($m_Map[$i]) ;same problem with isMap($m_Map[$i]), MapKeys($m_Map[$i]), MapAppend/MapRemove but NOT with MapExists($m_Map,$i) ConsoleWrite($i&": "&$m_Map[$i]&@CRLF) Next EndFunc Func MapDisplay2( ByRef $m_Map ) For $i In MapKeys($m_Map) isMap($m_Map[$i]) ConsoleWrite($i&": "&$m_Map[$i]&@CRLF) Next EndFunc The value is not lost or overwritten on the global map, only on the local map inside the function.
  13. After a restart it worked as intended. Sorry for the trouble.
  14. mLipok, of course i use only lowercase for abbrevs. Jos, the SCITE_USERHOME Env Variable is set and points to C:\Users\Qsek\AppData\Local\AutoIt v3\SciTE in which are all the property files and some folders.
  15. I have a big Problem. I did a fresh install of Autoit 3.3.14.1 with the autoit-v3-setup.exe and SciTE4AutoIt3.exe The Abbreviations are not working. The abbrev is marked red if i type it but space after or ctrl-b does nothing. Also when i start the Abbrev Manager i get "No User Abbreviations exist. Only Create function available". Everything is emtpy, User and Scite Abbrev. cannot Create, cannot reinstall. In Options> Open Abbrev File there is an empty file. There is also an AppData/Local/Autoit v3/Scite Folder where there is an abbrev.properties with 2 import lines and au3abbrev.properties with all the abbreviations in it. But the empty file i open with the Option Dialogue is in (install Dir)/Scite/abbrev.properties ? Again: this is a fresh install on a different harddrive, cleaned User Folder, AppData Folder and uninstalled previous versions of Autoit. Also tried the new Beta Files for Scite.
×
×
  • Create New...