<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://dataflex.wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Wil</id>
	<title>DataFlex Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://dataflex.wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Wil"/>
	<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Special:Contributions/Wil"/>
	<updated>2026-04-21T16:34:23Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://dataflex.wiki/index.php?title=StartProg&amp;diff=3676</id>
		<title>StartProg</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=StartProg&amp;diff=3676"/>
		<updated>2024-10-23T09:24:39Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;StartProg is a small CreateProcess wrapper function originally written by Bernhard Ponemayr.&lt;br /&gt;
&lt;br /&gt;
You can use it as an alternative to RunProgram and RunProgram Wait.&lt;br /&gt;
&lt;br /&gt;
This package has been sitting at the library section of the forum for years.&lt;br /&gt;
&lt;br /&gt;
The reason I put it at the wiki is to make it easier to find it back as searching for this at the forum always takes more time then it should be.&lt;br /&gt;
&lt;br /&gt;
Latest version is here: [https://support.dataaccess.com/Forums/showthread.php?50143-New-Startprog-pkg&amp;amp;p=356484#post356484 New StartProg DF 20.0+ version]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=StartProg&amp;diff=3675</id>
		<title>StartProg</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=StartProg&amp;diff=3675"/>
		<updated>2024-10-23T09:24:21Z</updated>

		<summary type="html">&lt;p&gt;Wil: Created page with &amp;quot;StartProg is a small CreateProcess wrapper function originally written by Bernhard Ponemayr.  You can use it as an alternative to RunProgram and RunProgram Wait.  This package has been sitting at the library section of the forum for years.  The reason I put it at the wiki is to make it easier to find it back as searching for this at the forum always takes more time then it should be.  Latest version is here: https://support.dataaccess.com/Forums/showthread.php?50143-Ne...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;StartProg is a small CreateProcess wrapper function originally written by Bernhard Ponemayr.&lt;br /&gt;
&lt;br /&gt;
You can use it as an alternative to RunProgram and RunProgram Wait.&lt;br /&gt;
&lt;br /&gt;
This package has been sitting at the library section of the forum for years.&lt;br /&gt;
&lt;br /&gt;
The reason I put it at the wiki is to make it easier to find it back as searching for this at the forum always takes more time then it should be.&lt;br /&gt;
&lt;br /&gt;
Latest version is here: [[https://support.dataaccess.com/Forums/showthread.php?50143-New-Startprog-pkg&amp;amp;p=356484#post356484 New StartProg DF 20.0+ version]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Rounding_Numbers&amp;diff=3674</id>
		<title>Rounding Numbers</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Rounding_Numbers&amp;diff=3674"/>
		<updated>2024-10-10T18:09:02Z</updated>

		<summary type="html">&lt;p&gt;Wil: /* Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Rounding Numbers =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039; The following has been taken from the DAW newsgroup, User Contributed Oct 6 2000 &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== MARF - A Mutually Agreed Rounding Function?! ==&lt;br /&gt;
&lt;br /&gt;
Aside from UI issues, OS and hardware problems, perhaps one of the most&lt;br /&gt;
frequently recurring themes in both the old DAC CompuServe Forum, and now&lt;br /&gt;
here, has been &#039;How to perform proper rounding of numeric values&#039;.&lt;br /&gt;
&lt;br /&gt;
Interestingly, each time the topic reappears as a new thread, nobody ever&lt;br /&gt;
refers the questioner back to the previous threads on the subject.  It is&lt;br /&gt;
always a great opportunity to air one&#039;s own (usually strictly limited)&lt;br /&gt;
solution to the problem!&lt;br /&gt;
&lt;br /&gt;
Well, I propose that we use this message thread to, if possible, finally&lt;br /&gt;
agree upon a proper specification and solution to this problem ... the one&lt;br /&gt;
that DAC forgot to supply us ... and finally lay this ghost to rest!&lt;br /&gt;
&lt;br /&gt;
So let me kick-off.&lt;br /&gt;
&lt;br /&gt;
Here is what I expect of a proper Rounding function:-&lt;br /&gt;
&lt;br /&gt;
(a) It should be able to cope with all numbers in the DataFlex numeric range&lt;br /&gt;
ie. ± 99,999,999,999,999.99999999.&lt;br /&gt;
&lt;br /&gt;
(b) Rounding &#039;&#039;&#039;up&#039;&#039;&#039; should occur when the digit to the right of the rounding&lt;br /&gt;
position is 5 or above, otherwise rounding &#039;&#039;&#039;down&#039;&#039;&#039; should occur.  I take this to be a reasonably &#039;international&#039;&lt;br /&gt;
convention.&lt;br /&gt;
&lt;br /&gt;
(c) It should be possible to round to any degree of precision.  In other&lt;br /&gt;
words, it should be capable of rounding to any position to the left of the&lt;br /&gt;
decimal delimiter as well as to the right of it.  This, after all, is a&lt;br /&gt;
frequent requirement in financial reporting.  So, for example, if I wish to&lt;br /&gt;
round to the nearest thousand, then a value of 72637.54 should be returned&lt;br /&gt;
as 73000.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I have attached a file named ROUNDNUM.FNC which contains a global function&lt;br /&gt;
that attempts to meet these requirements.  Use of the function, named&lt;br /&gt;
ROUND_NUMBER, is fully documented therein.&lt;br /&gt;
&lt;br /&gt;
My approach is substantially based on some code originally presented by&lt;br /&gt;
Hendrick van Niekerk in a CompuServe message in October 1997.  I note that&lt;br /&gt;
he has repeated the code in a message reply in the VDF NG on 11-Jun-2000.&lt;br /&gt;
&lt;br /&gt;
I prefer Hendrick&#039;s method to all the others I have yet seen.  His code is&lt;br /&gt;
actually contained in a macro command named ROUND THEN.  Basically all I&lt;br /&gt;
have done is to convert his macro into a global function and then extended&lt;br /&gt;
the scope of the code to provide for rounding to a more flexible degree of&lt;br /&gt;
precision.&lt;br /&gt;
&lt;br /&gt;
So ... well ... thanks Hendrick!&lt;br /&gt;
&lt;br /&gt;
Regards,&lt;br /&gt;
&lt;br /&gt;
Michael Pilsworth&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Source =&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
 // ===========================================================================&lt;br /&gt;
 //&lt;br /&gt;
 // The ROUND_NUMBER global function has been designed to return the rounded&lt;br /&gt;
 // value of a given &#039;numeric&#039; argument at a specified rounding precision.&lt;br /&gt;
 //&lt;br /&gt;
 // The function requires two arguments, as follows:-&lt;br /&gt;
 //&lt;br /&gt;
 // (a) The numeric value to be rounded, where the range of valid values is&lt;br /&gt;
 //     +/- 99,999,999,999,999.99999999.&lt;br /&gt;
 //&lt;br /&gt;
 // (b) The rounding precision required.  This must be an integer value in the&lt;br /&gt;
 //     range -13 to +8.  If a value outside this range is used, the nearest&lt;br /&gt;
 //     threshold value is substituted.&lt;br /&gt;
 //&lt;br /&gt;
 //     Values in the range +1 to +7 perform rounding on the decimal part of&lt;br /&gt;
 //     the number.  A value of +8 will perform no rounding at all.  A zero&lt;br /&gt;
 //     value will round to the nearest whole number.  Values -1 to -13 will&lt;br /&gt;
 //     round progressively to the left of the decimal point (a frequent&lt;br /&gt;
 //     requirement in financial reporting).&lt;br /&gt;
 //&lt;br /&gt;
 // If the result of the rounding produces a value outside the valid numeric&lt;br /&gt;
 // range (+/- 99,999,999,999,999.99999999) then a zero value is returned.&lt;br /&gt;
 //&lt;br /&gt;
 // Assumptions:-  The only assumptions made have been that the range of&lt;br /&gt;
 // numeric values and the limit of eight decimal places are unlikely to change&lt;br /&gt;
 // in the forseeable future.&lt;br /&gt;
 //&lt;br /&gt;
 // Examples:-&lt;br /&gt;
 //&lt;br /&gt;
 //  1st Argument      2nd Argument   Return Value&lt;br /&gt;
 //  ------------      ------------   ------------&lt;br /&gt;
 //  123456.87654321         8         123456.87654321&lt;br /&gt;
 //  123456.87654321         2         123456.88&lt;br /&gt;
 // -123456.87654321         2        -123456.88&lt;br /&gt;
 //  123456.98765432         0         123457&lt;br /&gt;
 // -123456.98765432        -1        -123460&lt;br /&gt;
 //  123456.98765432        -2         123500&lt;br /&gt;
 //  123456.98765432        -3         123000&lt;br /&gt;
 //  987654                 -4         990000&lt;br /&gt;
 //  987654                 -5        1000000&lt;br /&gt;
 //  987654                 -6        1000000&lt;br /&gt;
 //  987654                 -7              0&lt;br /&gt;
 //&lt;br /&gt;
 // ===========================================================================&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  Function Round_Number GLOBAL number nVal integer iRnd returns Number&lt;br /&gt;
    // If the rounding precision falls in the range -5 to +8, then return:-&lt;br /&gt;
    If (iRnd &amp;gt;= -5) Function_Return ;&lt;br /&gt;
    (Number(Abs(nVal) / nVal) * 0.5 / (Number(10 ^ (iRnd min 8))) + nVal ;&lt;br /&gt;
      / (Number(10 ^ (8 - (iRnd min 8)))) * (Number(10 ^ (8 - (iRnd min 8)))))&lt;br /&gt;
    // Else, where the rounding precision is in the range -6 to -13, return:-&lt;br /&gt;
    Function_Return ;&lt;br /&gt;
      (Number(Abs(nVal) / nVal) * 0.5 * (Number(10 ^ (Abs(iRnd) min 13))) ;&lt;br /&gt;
        + nVal / (Number(10 ^ 13)) / (Number(10 ^ ((Abs(iRnd) - 5) min 8))) ;&lt;br /&gt;
          * (Number(10 ^ 13)) * (Number(10 ^ ((Abs(iRnd) - 5) min 8))))&lt;br /&gt;
  End_Function&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* https://support.dataaccess.com/Forums/showthread.php?55971-Rounding-to-nearest-5-cents&lt;br /&gt;
* https://support.dataaccess.com/Forums/showthread.php?70658-Multiplying-two-numbers-together-and-rounding-them-up-handy&lt;br /&gt;
&lt;br /&gt;
[[Category: Basics]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Codejock&amp;diff=3673</id>
		<title>Codejock</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Codejock&amp;diff=3673"/>
		<updated>2024-07-31T17:29:02Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Code Jock is a suite of components that enhance the graphical interface to DataFlex.&lt;br /&gt;
It is included in the development environment since Visual DataFlex version 12.0.&lt;br /&gt;
&lt;br /&gt;
* [[Code Jock menus]]&lt;br /&gt;
* [[Dynamic codejock menus from a database]]&lt;br /&gt;
* [[How to add your own items to the default Codejock Context menu]]&lt;br /&gt;
* [[Add icons with subset of images to CodeJock CommandBars]]&lt;br /&gt;
* [[Codejock Grid with ProgressBar]]&lt;br /&gt;
* [[Time edit grid column for cCJGrid]]&lt;br /&gt;
* [[Apply color to codejock grid column headers]]&lt;br /&gt;
* [[cCJGrid custom row height]]&lt;br /&gt;
&lt;br /&gt;
* [https://support.dataaccess.com/Forums/showthread.php?39317-Where-to-download VDFSig Codejock Library (Where to download post at teh forum) ]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Codejock]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=REST&amp;diff=3672</id>
		<title>REST</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=REST&amp;diff=3672"/>
		<updated>2024-03-16T14:07:56Z</updated>

		<summary type="html">&lt;p&gt;Wil: /* External references */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
With DataFlex you can create RESTful web services as well as consume those web services.&lt;br /&gt;
&lt;br /&gt;
== Client side ==&lt;br /&gt;
Consuming [https://en.wikipedia.org/wiki/Representational_state_transfer REST] services was made a lot easier since DataFlex 19.0 when it added native [[JSON]] support.&lt;br /&gt;
&lt;br /&gt;
Consume a REST service:&lt;br /&gt;
See [https://docs.dataaccess.com/dataflexhelp/mergedProjects/VDFClassRef/cJsonHttpTransfer.htm cJsonHttpTransfer] and [https://docs.dataaccess.com/dataflexhelp/mergedProjects/Welcome/JSON_Parsing_and_Transfer.htm JSON Parsing and Transfer]&lt;br /&gt;
&lt;br /&gt;
You can find a demo of how-to use cJsonHttpTransfer in DAWs WebOrder workspace.&lt;br /&gt;
&lt;br /&gt;
== Server side ==&lt;br /&gt;
Creating REST web services has been made easy since DataFlex 19.1 with the introduction of the [https://docs.dataaccess.com/dataflexhelp/mergedProjects/VDFClassRef/cWebHttpHandler.htm cWebHttpHandler] handler.&lt;br /&gt;
&lt;br /&gt;
For an example see the DemoSimpleRestService.wo file in the WebOrder example workspace.&lt;br /&gt;
&lt;br /&gt;
You can create a REST service with earlier DataFlex versions, see [https://www.unicorninterglobal.com/Company-White-Papers-Creating-RESTful-JSON-Web-Services-in-DataFlex-868 here] for how-to do so in DataFlex 19.0, but it is probably better to use DataFlex 19.1 in that case.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[[RESTful Service Theory]]&lt;br /&gt;
*[[RESTful Services in DataFlex]]&lt;br /&gt;
*[[Consuming RESTful Services in DataFlex]]&lt;br /&gt;
*[[Creating RESTful Services in DataFlex]]&lt;br /&gt;
*[[A Simple RESTful Service]]&lt;br /&gt;
*[[Using the REST Library]]&lt;br /&gt;
&lt;br /&gt;
== External references ==&lt;br /&gt;
&lt;br /&gt;
*[http://salzlechner.com/dev/2016/03/02/interfacing-dataflex-restful-web-services/ Interfacing DataFlex RESTful web services] ([[User: Starzen|Michael Salzlechner]])&lt;br /&gt;
*[https://docs.google.com/document/d/1N3BvvygKfjKO_5TMosWrR8aahI-5VOz6-z-8jSqA_to/edit?usp=sharing Synergy 2019 REST APIs Course Exercise Instructions] ([[User: Mikepeat|Mike Peat]])&lt;br /&gt;
*[https://learning.dataaccess.com/courses/synergy-2019/how-to-build-a-restful-api-in-dataflex-19.1/ Synergy 2019 presentation &amp;quot;Building RESTful APIs in DataFlex&amp;quot;] ([[User: Mikepeat|Mike Peat]])&lt;br /&gt;
*[https://support.dataaccess.com/Forums/forumdisplay.php?59-OAuth-RESTFul-amp-Web-API-Integration OAuth Restful &amp;amp; Web API integration] section of the [https://support.dataaccess.com/Forums/forum.php Data Access Support Forum]&lt;br /&gt;
Sourced from [https://support.dataaccess.com/Forums/showthread.php?64503-New-REST-support forum post: New REST support]&lt;br /&gt;
* https://tools.chilkat.io/curl.cshtml (generate DataFlex code to use with Chilkat)&lt;br /&gt;
* [https://github.com/DataFlexCode/RestGen2022 RestGen2022] A tool to generate a DataFlex struct from JSON&lt;br /&gt;
&lt;br /&gt;
[[Category:REST]]&lt;br /&gt;
[[Category:Web Services]]&lt;br /&gt;
[[Category:System Integration]]&lt;br /&gt;
[[Category:JSON]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=JSON_and_Nullable_elements&amp;diff=3671</id>
		<title>JSON and Nullable elements</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=JSON_and_Nullable_elements&amp;diff=3671"/>
		<updated>2024-03-08T21:46:53Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== The nullable JSON issue ===&lt;br /&gt;
&lt;br /&gt;
Using DataFlex it is very convenient to fill up your JSON data from a struct when using the [https://docs.dataaccess.com/dataflexhelp/mergedProjects/VDFClassRef/cJsonObject.htm cJSONOjbect] class. See for example our [[Create JSON from struct]] article.&lt;br /&gt;
&lt;br /&gt;
Quite often that [[JSON]] data is then send to a [[REST]] service and depending on that service they might not want to receive all the elements in your JSON in order to work correctly.&lt;br /&gt;
&lt;br /&gt;
There&#039;s also the issue of receiving JSON data with a null in there and not being able to process that automatically via a struct as DataFlex variables are not nullable.&lt;br /&gt;
&lt;br /&gt;
This has been debated before in the forum (1) a few times and currently the official way to do so is by traversing the JSON data structure and then removing the members that the other side does not want to process by using the [https://docs.dataaccess.com/dataflexhelp/mergedProjects/VDFClassRef/cJsonObject-Procedure-RemoveMember.htm RemoveMember] method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
  Send RemoveMember of hoJSON &amp;quot;myElement&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please note that when you use JsonToDataType to go from JSON to a struct that you now have to turn off the strict checking if all members are available with&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
  Set pbRequireAllMembers of hoJSON to False&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That works fine for simple JSON structures.&lt;br /&gt;
If your structure has another level then your code becomes more difficult to write pretty fast. &lt;br /&gt;
&lt;br /&gt;
Take for example the following simplified JSON&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;Sales&amp;quot;,&lt;br /&gt;
  &amp;quot;companyCode&amp;quot;: &amp;quot;DEMO&amp;quot;,&lt;br /&gt;
  &amp;quot;date&amp;quot;: &amp;quot;2013-06-29&amp;quot;,&lt;br /&gt;
  &amp;quot;customerCode&amp;quot;: &amp;quot;ABC&amp;quot;,&lt;br /&gt;
  &amp;quot;addresses&amp;quot;: {&lt;br /&gt;
    &amp;quot;shipTo&amp;quot;: {&lt;br /&gt;
      &amp;quot;line1&amp;quot;: &amp;quot;143 Main Street&amp;quot;,&lt;br /&gt;
      &amp;quot;city&amp;quot;: &amp;quot;Irvine&amp;quot;,&lt;br /&gt;
      &amp;quot;region&amp;quot;: &amp;quot;CA&amp;quot;,&lt;br /&gt;
      &amp;quot;country&amp;quot;: &amp;quot;US&amp;quot;,&lt;br /&gt;
      &amp;quot;postalCode&amp;quot;: &amp;quot;92614&amp;quot;,&lt;br /&gt;
      &amp;quot;longitude&amp;quot;: 0.0,&lt;br /&gt;
      &amp;quot;latitude&amp;quot;: 0.0&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;shipFrom&amp;quot;: {&lt;br /&gt;
      ... more details ...&lt;br /&gt;
    }&lt;br /&gt;
  }}&lt;br /&gt;
&lt;br /&gt;
If that&#039;s filled in from a struct and your REST service gets confused if you pass both address as well as long/lat coordinates with value 0.0 then you have to remove the longitude/latitude elements.&lt;br /&gt;
&lt;br /&gt;
To do this your code could look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
..&lt;br /&gt;
      Get Create (RefClass(cJsonObject)) to hoJsonRequest&lt;br /&gt;
      If (hoJsonRequest) Begin&lt;br /&gt;
        Send DataTypeToJson Of hoJsonRequest data&lt;br /&gt;
        If (data.addresses.shipto.latitude=0.0 and data.addresses.shipto.longitude=0.0) Begin&lt;br /&gt;
          Send RemoveAddressCoordinates hoJsonRequest &amp;quot;shipTo&amp;quot; &amp;quot;latitude&amp;quot;&lt;br /&gt;
          Send RemoveAddressCoordinates hoJsonRequest &amp;quot;shipTo&amp;quot; &amp;quot;longitude&amp;quot;&lt;br /&gt;
        End&lt;br /&gt;
..&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with the RemoveAddressCoordinates method looking like this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
  //&lt;br /&gt;
  // Used to strip longitude/latitude data from json&lt;br /&gt;
  //&lt;br /&gt;
  Procedure RemoveAddressCoordinates Handle hoJsonRequest String sAddressType String sCoord&lt;br /&gt;
    Integer eType&lt;br /&gt;
    Handle  hoAddresses hoAddressType&lt;br /&gt;
    &lt;br /&gt;
    Get MemberJsonType of hoJsonRequest &amp;quot;addresses&amp;quot; to eType&lt;br /&gt;
    If (eType=jsonTypeObject) Begin&lt;br /&gt;
      Get Member of hoJsonRequest &amp;quot;addresses&amp;quot; to hoAddresses&lt;br /&gt;
      If (hoAddresses) Begin&lt;br /&gt;
        Get MemberJsonType of hoAddresses sAddressType to eType  // &amp;quot;shipTo&amp;quot;&lt;br /&gt;
        If (eType=jsonTypeObject) Begin&lt;br /&gt;
          Get Member Of hoAddresses sAddressType To hoAddressType&lt;br /&gt;
          If (hoAddressType) Begin&lt;br /&gt;
            Send RemoveMember Of hoAddressType sCoord // &amp;quot;latitude&amp;quot;&lt;br /&gt;
            Send Destroy Of hoAddressType&lt;br /&gt;
          End&lt;br /&gt;
        End&lt;br /&gt;
        Send Destroy Of hoAddresses&lt;br /&gt;
      End&lt;br /&gt;
    End&lt;br /&gt;
  End_Procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Yes it&#039;s readable, No it&#039;s not so easy to support once you get multiple levels deep for your address element as you now have to make sure you destroy the objects etc..&lt;br /&gt;
&lt;br /&gt;
=== The RemoveNamedMember method ===&lt;br /&gt;
&lt;br /&gt;
So when looking at the line with the actual condition on when to remove a specific element :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
  If (data.addresses.shipto.latitude=0.0 and data.addresses.shipto.longitude=0.0) Begin&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
it looked like it would be good to have a method that could take care of this in one line as well.&lt;br /&gt;
&lt;br /&gt;
eg. this would be nice to have:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
  If (data.addresses.shipto.latitude=0.0 and data.addresses.shipto.longitude=0.0) Begin&lt;br /&gt;
    Get RemoveNamedMember hoJsonRequest &amp;quot;addresses.shipTo.latitude&amp;quot;&lt;br /&gt;
    Get RemoveNamedMember hoJsonRequest &amp;quot;addresses.shipTo.longitude&amp;quot;&lt;br /&gt;
  End&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
it will then also work for a json structure where the address is a level deeper without having to write new code.&lt;br /&gt;
&lt;br /&gt;
eg.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
    Get RemoveNamedMember hoJsonRequest &amp;quot;Returns.addresses.shipTo.longitude&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Turned out it was fairly easy to write (easier than writing this post!)&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  //&lt;br /&gt;
  // Used to strip a named/value pair from json&lt;br /&gt;
  // You can use this to directly remove a JSON member at a lower level from the JSON&lt;br /&gt;
  // object passed via hoJSON.&lt;br /&gt;
  // The member to be removed uses the exact JSON member names separated by dots.&lt;br /&gt;
  // Beware that JSON member names are case sensitive!&lt;br /&gt;
  //&lt;br /&gt;
  // If the member does not exist a runtime error will be triggered.&lt;br /&gt;
  // Eg.&lt;br /&gt;
  //  Send RemoveNamedMember hoJsonRequest &amp;quot;Order.addresses.shipTo.latitude&amp;quot;&lt;br /&gt;
  //&lt;br /&gt;
  Procedure RemoveNamedMember Handle hoJson String sName&lt;br /&gt;
     Integer iDotPos&lt;br /&gt;
     Integer eType&lt;br /&gt;
     Handle  hoChild&lt;br /&gt;
     String  sMember&lt;br /&gt;
     &lt;br /&gt;
     Move (Pos(&amp;quot;.&amp;quot;,sName)) to iDotPos&lt;br /&gt;
     If (iDotPos&amp;gt;0) Begin&lt;br /&gt;
       Move (Left(sName,iDotPos-1)) To sMember&lt;br /&gt;
       Move (Replace(sMember+&amp;quot;.&amp;quot;,sName,&amp;quot;&amp;quot;)) To sName&lt;br /&gt;
       //Get HasMember of hoJson sMember to bHasMember &amp;lt;-- use this if you want to filter the runtime error (we currently do not)&lt;br /&gt;
       Get MemberJsonType of hoJson sMember to eType&lt;br /&gt;
       If (eType=jsonTypeObject) Begin&lt;br /&gt;
         Get Member of hoJson sMember to hoChild&lt;br /&gt;
         If (hoChild) Begin&lt;br /&gt;
           Send RemoveNamedMember hoChild sName&lt;br /&gt;
           Send Destroy Of hoChild&lt;br /&gt;
         End&lt;br /&gt;
       End&lt;br /&gt;
     End&lt;br /&gt;
     Else Begin&lt;br /&gt;
       Send RemoveMember Of hoJson sName&lt;br /&gt;
     End&lt;br /&gt;
  End_Procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that if you don&#039;t want the runtime error that you can use the HasMember test. &lt;br /&gt;
&lt;br /&gt;
We don&#039;t use that as we always first convert from struct so we know the element exists. If the element is not there then there&#039;s likely a case sensitivity issue, so getting a runtime error helps when debugging your code.&lt;br /&gt;
&lt;br /&gt;
Of course a little while later I bump into a more complicated issue where the removed member is in an array. Lucky for me, in an single dimension array. This can be taken care of like this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  //&lt;br /&gt;
  // Used to strip longitude/latitude data from json in a CreateTransactionModel&lt;br /&gt;
  // You can use it to directly remove a JSON member at a lower level from the JSON&lt;br /&gt;
  // object passed via hoJSON.&lt;br /&gt;
  // The member to be removed uses the exact JSON member names separated by dots and&lt;br /&gt;
  // this is case sensitive.&lt;br /&gt;
  //&lt;br /&gt;
  // If the member does not exist a runtime error will be triggered.&lt;br /&gt;
  // Eg.&lt;br /&gt;
  //  Send RemoveNamedMember hoJsonRequest &amp;quot;newTransaction.addresses[2].shipTo.latitude&amp;quot;&lt;br /&gt;
  //&lt;br /&gt;
  Procedure RemoveNamedMember Handle hoJson String sName&lt;br /&gt;
     Integer iDotPos&lt;br /&gt;
     Integer iLSBPos iIndex&lt;br /&gt;
     Integer eType&lt;br /&gt;
     Handle  hoChild&lt;br /&gt;
     Handle  hoArray&lt;br /&gt;
     String  sMember sIndex&lt;br /&gt;
     &lt;br /&gt;
     Move (Pos(&amp;quot;.&amp;quot;,sName)) to iDotPos&lt;br /&gt;
     If (iDotPos&amp;gt;0) Begin&lt;br /&gt;
       Move (Left(sName,iDotPos-1)) To sMember&lt;br /&gt;
       Move (Replace(sMember+&amp;quot;.&amp;quot;,sName,&amp;quot;&amp;quot;)) To sName&lt;br /&gt;
       Move (Pos(&amp;quot;[&amp;quot;,sMember)) To iLSBPos&lt;br /&gt;
       If (iLSBPos&amp;gt;0) Begin&lt;br /&gt;
         Move (Right(sMember,(length(sMember)+1)-iLSBPos)) To sIndex&lt;br /&gt;
         Move (Replace(sIndex,sMember,&amp;quot;&amp;quot;)) To sMember&lt;br /&gt;
         Move (Replace(&amp;quot;[&amp;quot;,sIndex,&amp;quot;&amp;quot;)) To sIndex&lt;br /&gt;
         Move (Replace(&amp;quot;]&amp;quot;,sIndex,&amp;quot;&amp;quot;)) To sIndex&lt;br /&gt;
         Move (Cast(sIndex,Integer))   To iIndex&lt;br /&gt;
       End&lt;br /&gt;
       //Get HasMember of hoJson sMember to bHasMember &amp;lt;-- use this if you want to filter the runtime error (we currently do not)&lt;br /&gt;
       Get MemberJsonType of hoJson sMember to eType&lt;br /&gt;
       If (eType=jsonTypeObject) Begin&lt;br /&gt;
         Get Member of hoJson sMember to hoChild&lt;br /&gt;
         If (hoChild) Begin&lt;br /&gt;
           Send RemoveNamedMember hoChild sName&lt;br /&gt;
           Send Destroy Of hoChild&lt;br /&gt;
         End&lt;br /&gt;
       End&lt;br /&gt;
       Else If (eType=jsonTypeArray) Begin&lt;br /&gt;
         Get Member of hoJson sMember to hoArray&lt;br /&gt;
         If (hoArray) Begin&lt;br /&gt;
           Get MemberByIndex of hoArray iIndex to hoChild&lt;br /&gt;
           If (hoChild) Begin&lt;br /&gt;
             Send RemoveNamedMember hoChild sName&lt;br /&gt;
             Send Destroy Of hoChild&lt;br /&gt;
           End&lt;br /&gt;
           Send Destroy Of hoArray&lt;br /&gt;
         End&lt;br /&gt;
       End&lt;br /&gt;
     End&lt;br /&gt;
     Else Begin&lt;br /&gt;
       Send RemoveMember Of hoJson sName&lt;br /&gt;
     End&lt;br /&gt;
  End_Procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Harm&#039;s RemoveEmptyMembers method ===&lt;br /&gt;
&lt;br /&gt;
Harm Wibier posted a solution where you can automatically remove elements which have a value of 0 or in the case of a string element where the string element is an empty string. See also (2)&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
//&lt;br /&gt;
//  Recursive function going over JSON objects removing all empty strings, 0 and NULL values of objects (not from arrays).&lt;br /&gt;
//&lt;br /&gt;
//  Params:&lt;br /&gt;
//      hoJsonObj       Handle of the JSON object to process.&lt;br /&gt;
//      bEmptyString    If true empty string values will be removed.&lt;br /&gt;
//      bZeroNumber     If true all numeric 0 values will be removed.&lt;br /&gt;
//      bNull           If true all NULL values will be removed.&lt;br /&gt;
//&lt;br /&gt;
Procedure RemoveEmptyMembers Handle hoJsonObj Boolean bEmptyString Boolean bZeroNumber Boolean bNull&lt;br /&gt;
    Integer iTo iMember iType&lt;br /&gt;
    Handle hoMember&lt;br /&gt;
    String sMemberName&lt;br /&gt;
    Boolean bRemove&lt;br /&gt;
    &lt;br /&gt;
    Get MemberCount of hoJsonObj to iTo&lt;br /&gt;
    For iMember from 0 to (iTo - 1)&lt;br /&gt;
        Move False to bRemove&lt;br /&gt;
        &lt;br /&gt;
        Get MemberByIndex of hoJsonObj iMember to hoMember&lt;br /&gt;
        &lt;br /&gt;
        Get JsonType of hoMember to iType&lt;br /&gt;
        &lt;br /&gt;
        Case Begin&lt;br /&gt;
            Case (iType = jsonTypeString)&lt;br /&gt;
                If (bEmptyString) Begin&lt;br /&gt;
                    Move (JsonValue(hoMember) = &amp;quot;&amp;quot;) to bRemove&lt;br /&gt;
                End&lt;br /&gt;
                Case Break&lt;br /&gt;
            Case (iType = jsonTypeInteger)&lt;br /&gt;
                If (bZeroNumber) Begin&lt;br /&gt;
                    Move (JsonValue(hoMember) = 0) to bRemove&lt;br /&gt;
                End&lt;br /&gt;
                Case Break&lt;br /&gt;
            Case (iType = jsonTypeNull) &lt;br /&gt;
                Move bNull to bRemove&lt;br /&gt;
                Case Break&lt;br /&gt;
            Case (iType = jsonTypeObject or iType = jsonTypeArray) Begin&lt;br /&gt;
                Send RemoveEmptyMembers hoMember bEmptyString bZeroNumber bNull&lt;br /&gt;
                Case Break&lt;br /&gt;
            End&lt;br /&gt;
        Case End&lt;br /&gt;
        &lt;br /&gt;
        //  Only remove empty members of objects (not from arrays)&lt;br /&gt;
        If (bRemove and IsOfJsonType(hoJsonObj, jsonTypeObject)) Begin&lt;br /&gt;
            Get MemberNameByIndex of hoJsonObj iMember to sMemberName&lt;br /&gt;
            Send RemoveMember of hoJsonObj sMemberName&lt;br /&gt;
            Decrement iMember&lt;br /&gt;
            Decrement iTo&lt;br /&gt;
        End&lt;br /&gt;
        &lt;br /&gt;
        Send Destroy of hoMember&lt;br /&gt;
    Loop&lt;br /&gt;
End_Procedure&lt;br /&gt;
&lt;br /&gt;
// Use like this:&lt;br /&gt;
Send RemoveEmptyMembers hoJson False False True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That works, but I&#039;m personally a bit cautious about removing all elements that have value &amp;quot;0&amp;quot;. &lt;br /&gt;
Sometimes we want pass that actual value, empty or zero does not equal null. There might be another element with the value 0 that should not be removed. However, sometimes it is exactly what you need.&lt;br /&gt;
&lt;br /&gt;
If you just want to remove the nulls before you move the data to a struct, then perhaps Mike Peat&#039;s variant of Harm&#039;s code is a bit more clear:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
// Version of Harm&#039;s procedure, just for nulls.&lt;br /&gt;
Procedure RemoveNullMembers Handle hoJsonObj&lt;br /&gt;
    Integer iTo iMember iType&lt;br /&gt;
    Handle hoMember&lt;br /&gt;
    String sMemberName&lt;br /&gt;
    Boolean bRemove&lt;br /&gt;
    &lt;br /&gt;
    Get MemberCount of hoJsonObj to iTo&lt;br /&gt;
    Decrement iTo&lt;br /&gt;
&lt;br /&gt;
    For iMember from 0 to iTo&lt;br /&gt;
        Move False to bRemove&lt;br /&gt;
        Get MemberByIndex of hoJsonObj iMember to hoMember&lt;br /&gt;
        Get JsonType of hoMember to iType&lt;br /&gt;
         &lt;br /&gt;
        If (iType = jsonTypeNull) ;&lt;br /&gt;
                Move True to bRemove&lt;br /&gt;
        Else If (iType = jsonTypeObject or iType = jsonTypeArray) ;&lt;br /&gt;
                Send RemoveNullMembers hoMember&lt;br /&gt;
         &lt;br /&gt;
        If bRemove Begin&lt;br /&gt;
&lt;br /&gt;
            If (IsOfJsonType(hoJsonObj, jsonTypeObject)) Begin&lt;br /&gt;
                Get MemberNameByIndex of hoJsonObj iMember to sMemberName&lt;br /&gt;
                Send RemoveMember of hoJsonObj sMemberName&lt;br /&gt;
                Decrement iMember&lt;br /&gt;
                Decrement iTo&lt;br /&gt;
            End&lt;br /&gt;
            Else If (IsOfJsonType(hoJsonObj, jsonTypeArray)) Begin&lt;br /&gt;
                Send RemoveMember of hoJsonObj iMember&lt;br /&gt;
                Decrement iMember&lt;br /&gt;
                Decrement iTo&lt;br /&gt;
            End&lt;br /&gt;
&lt;br /&gt;
        End&lt;br /&gt;
         &lt;br /&gt;
        Send Destroy of hoMember&lt;br /&gt;
    Loop&lt;br /&gt;
&lt;br /&gt;
End_Procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
See also (3)&lt;br /&gt;
&lt;br /&gt;
=== External references ===&lt;br /&gt;
&lt;br /&gt;
* (1) [https://support.dataaccess.com/Forums/showthread.php?64157-YAFR-DataTypeToJson-beyond-19-1 YAFR DataTypeToJson beyond 19.1] loong and mostly off topic debate at the forum about null support and JSON&lt;br /&gt;
* (2) [https://support.dataaccess.com/Forums/showthread.php?62437-JsonToDataType&amp;amp;p=331876#post331876 JsonToDataType] Harm Wibier&#039;s solution&lt;br /&gt;
* (3) [https://support.dataaccess.com/Forums/showthread.php?64923-Null-json&amp;amp;p=348369#post348369 Json-Nulls] Mike Peat his variant&lt;br /&gt;
* [https://support.dataaccess.com/Forums/showthread.php?62358-Use-of-HasMember-of-cJSON-class-when-used-with-arrays&amp;amp;p=331630#post331630 RemoveNulls function by Mike Peat]&lt;br /&gt;
&lt;br /&gt;
[[Category:REST]]&lt;br /&gt;
[[Category:JSON]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Struct_array_as_a_Web_Property&amp;diff=3670</id>
		<title>Struct array as a Web Property</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Struct_array_as_a_Web_Property&amp;diff=3670"/>
		<updated>2023-07-25T12:30:12Z</updated>

		<summary type="html">&lt;p&gt;Wil: categorizing&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Complex web properties, such as structs and/or arrays, have been supported since DataFlex 18.1. &lt;br /&gt;
&lt;br /&gt;
The documentation on this however is extremely thin.&lt;br /&gt;
It doesn&#039;t exist at the time of writing this, so you are left on your own on how-to figure out how that works.&lt;br /&gt;
&lt;br /&gt;
The usage of a struct requires that you serialize/deserialize the data against a matching javascript object, just like when you pass a parameter.&lt;br /&gt;
Perhaps there&#039;s a better way, but I am not aware of that.&lt;br /&gt;
&lt;br /&gt;
What follows is a simple code example taken from the syncfusion library, to give you an idea on how this works.&lt;br /&gt;
&lt;br /&gt;
On the DataFlex side:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Struct tCarouselItem&lt;br /&gt;
  String sImage&lt;br /&gt;
  String sAltText&lt;br /&gt;
  String sCaption&lt;br /&gt;
End_Struct&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
... snip ....&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    Procedure Construct_Object&lt;br /&gt;
        Forward Send Construct_Object&lt;br /&gt;
        &lt;br /&gt;
        { WebProperty=Client }&lt;br /&gt;
        Property tCarouselItem[]  pCarouselItems&lt;br /&gt;
&lt;br /&gt;
... snip ....&lt;br /&gt;
&lt;br /&gt;
    //&lt;br /&gt;
    Procedure LoadImages&lt;br /&gt;
        tCarouselItem   CarouselItem&lt;br /&gt;
        tCarouselItem[] CarouselItems&lt;br /&gt;
        ... some code filling the array and putting that in array variable CarouselItems&lt;br /&gt;
        Send LoadData sData&lt;br /&gt;
        WebSet pCarouselItems to CarouselItems&lt;br /&gt;
    End_Procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So we can use a WebSet to transfer the data, just like with other properties.&lt;br /&gt;
&lt;br /&gt;
On the javascript side:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
//&lt;br /&gt;
// carousel data.&lt;br /&gt;
//&lt;br /&gt;
tActionCarouselItemFormat = {&lt;br /&gt;
        image : df.tString,&lt;br /&gt;
        altText : df.tString,&lt;br /&gt;
        caption : df.tString&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
..snip...&lt;br /&gt;
&lt;br /&gt;
sf.WebCarousel = function WebCarousel(sName, oParent) {&lt;br /&gt;
    // Forward send constructor&lt;br /&gt;
    sf.WebCarousel.base.constructor.call(this, sName, oParent);&lt;br /&gt;
&lt;br /&gt;
    // Properties:&lt;br /&gt;
... snip ....&lt;br /&gt;
    this.prop(df.tString,&amp;quot;psSyncfusionLicense&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    this.prop(df.tAdv,&amp;quot;pCarouselItems&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
..snip ...&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
    carouselItemsChanged : function() {&lt;br /&gt;
        let carousel=this._osfWebCarousel;&lt;br /&gt;
        let tData=null;&lt;br /&gt;
        let tItems=null;&lt;br /&gt;
        if(carousel){&lt;br /&gt;
            tData = this.pCarouselItems;&lt;br /&gt;
            tItems = df.sys.vt.deserialize(tData, [tActionCarouselItemFormat] );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the javascript end after getting the advanced client property into a variable, you only have to deserialize it to get at the data.&lt;br /&gt;
&lt;br /&gt;
[[Category: Web Applications]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Struct_array_as_a_Web_Property&amp;diff=3669</id>
		<title>Struct array as a Web Property</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Struct_array_as_a_Web_Property&amp;diff=3669"/>
		<updated>2023-07-25T12:26:05Z</updated>

		<summary type="html">&lt;p&gt;Wil: Created page with &amp;quot;Complex web properties, such as structs and/or arrays, have been supported since DataFlex 18.1.   The documentation on this however is extremely thin. It doesn&amp;#039;t exist at the time of writing this, so you are left on your own on how-to figure out how that works.  The usage of a struct requires that you serialize/deserialize the data against a matching javascript object, just like when you pass a parameter. Perhaps there&amp;#039;s a better way, but I am not aware of that.  What fo...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Complex web properties, such as structs and/or arrays, have been supported since DataFlex 18.1. &lt;br /&gt;
&lt;br /&gt;
The documentation on this however is extremely thin.&lt;br /&gt;
It doesn&#039;t exist at the time of writing this, so you are left on your own on how-to figure out how that works.&lt;br /&gt;
&lt;br /&gt;
The usage of a struct requires that you serialize/deserialize the data against a matching javascript object, just like when you pass a parameter.&lt;br /&gt;
Perhaps there&#039;s a better way, but I am not aware of that.&lt;br /&gt;
&lt;br /&gt;
What follows is a simple code example taken from the syncfusion library, to give you an idea on how this works.&lt;br /&gt;
&lt;br /&gt;
On the DataFlex side:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Struct tCarouselItem&lt;br /&gt;
  String sImage&lt;br /&gt;
  String sAltText&lt;br /&gt;
  String sCaption&lt;br /&gt;
End_Struct&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
... snip ....&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    Procedure Construct_Object&lt;br /&gt;
        Forward Send Construct_Object&lt;br /&gt;
        &lt;br /&gt;
        { WebProperty=Client }&lt;br /&gt;
        Property tCarouselItem[]  pCarouselItems&lt;br /&gt;
&lt;br /&gt;
... snip ....&lt;br /&gt;
&lt;br /&gt;
    //&lt;br /&gt;
    Procedure LoadImages&lt;br /&gt;
        tCarouselItem   CarouselItem&lt;br /&gt;
        tCarouselItem[] CarouselItems&lt;br /&gt;
        ... some code filling the array and putting that in array variable CarouselItems&lt;br /&gt;
        Send LoadData sData&lt;br /&gt;
        WebSet pCarouselItems to CarouselItems&lt;br /&gt;
    End_Procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So we can use a WebSet to transfer the data, just like with other properties.&lt;br /&gt;
&lt;br /&gt;
On the javascript side:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
//&lt;br /&gt;
// carousel data.&lt;br /&gt;
//&lt;br /&gt;
tActionCarouselItemFormat = {&lt;br /&gt;
        image : df.tString,&lt;br /&gt;
        altText : df.tString,&lt;br /&gt;
        caption : df.tString&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
..snip...&lt;br /&gt;
&lt;br /&gt;
sf.WebCarousel = function WebCarousel(sName, oParent) {&lt;br /&gt;
    // Forward send constructor&lt;br /&gt;
    sf.WebCarousel.base.constructor.call(this, sName, oParent);&lt;br /&gt;
&lt;br /&gt;
    // Properties:&lt;br /&gt;
... snip ....&lt;br /&gt;
    this.prop(df.tString,&amp;quot;psSyncfusionLicense&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    this.prop(df.tAdv,&amp;quot;pCarouselItems&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
..snip ...&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
    carouselItemsChanged : function() {&lt;br /&gt;
        let carousel=this._osfWebCarousel;&lt;br /&gt;
        let tData=null;&lt;br /&gt;
        let tItems=null;&lt;br /&gt;
        if(carousel){&lt;br /&gt;
            tData = this.pCarouselItems;&lt;br /&gt;
            tItems = df.sys.vt.deserialize(tData, [tActionCarouselItemFormat] );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the javascript end after getting the advanced client property into a variable, you only have to deserialize it to get at the data.&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Using_cWebHttpHandler_with_JSON_instead_of_tWebValueTree&amp;diff=3668</id>
		<title>Using cWebHttpHandler with JSON instead of tWebValueTree</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Using_cWebHttpHandler_with_JSON_instead_of_tWebValueTree&amp;diff=3668"/>
		<updated>2023-07-10T22:13:30Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;From this forum post: https://support.dataaccess.com/Forums/showthread.php?68231-ToDo-Describe-call-mode-and-a-few-more-questions&amp;amp;p=371095#post371095&lt;br /&gt;
&lt;br /&gt;
Reposting it here so I can quickly find it next time I need it (sorry, not sorry)&lt;br /&gt;
&lt;br /&gt;
It is indeed true that for most situations the tWebValueTree is not needed any more. ClientActions and ServerActions can now use JSON Handles or structs &amp;amp; arrays that are directly serialized. So when calling a server action you can now do the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
//  Create data objects    &lt;br /&gt;
var oData =  {&lt;br /&gt;
    labels : [&amp;quot;January&amp;quot;,&amp;quot;February&amp;quot;,&amp;quot;March&amp;quot;,&amp;quot;April&amp;quot;,&amp;quot;May&amp;quot;,&amp;quot;June&amp;quot;,&amp;quot;July&amp;quot;],&lt;br /&gt;
    datasets : [{&lt;br /&gt;
        strokeColor : &amp;quot;rgba(220,220,220,1)&amp;quot;,&lt;br /&gt;
        data : [65,59,90,81,56,55,40]&lt;br /&gt;
    },{&lt;br /&gt;
        strokeColor : &amp;quot;rgba(151,187,205,1)&amp;quot;,&lt;br /&gt;
        data : [28,48,40,19,96,27,100]&lt;br /&gt;
    }]&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
//  Send call to the server&lt;br /&gt;
this.serverAction(&amp;quot;ProcessData2&amp;quot;, [ 2, 1 ], oData, function(oEvent){&lt;br /&gt;
    alert(oEvent.sReturnValue);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
//  Function called as server action&lt;br /&gt;
Function ProcessData2 Integer iParam1 Integer iParam2 Returns String&lt;br /&gt;
    tActionData tData&lt;br /&gt;
    Handle hoJson&lt;br /&gt;
    &lt;br /&gt;
    //  Retrieve and deserialize data&lt;br /&gt;
    Get phoActionJsonData to hoJson&lt;br /&gt;
    Get JsonToDataType of hoJson to tData&lt;br /&gt;
    &lt;br /&gt;
    Function_Return tData.labels[3]&lt;br /&gt;
End_Function&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So instead of ptActionData you use phoActionJsonData which gives a cJsonObject representing the data. Note that you do not have to cleanup this JSON Handle.&lt;br /&gt;
&lt;br /&gt;
For client actions you can do the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
Procedure ProcessDataOnClient2&lt;br /&gt;
    //  Send the client action&lt;br /&gt;
    String[] aParams&lt;br /&gt;
    tActionData tData&lt;br /&gt;
     &lt;br /&gt;
    //  Generate some data&lt;br /&gt;
    Move &amp;quot;Januari&amp;quot;      to tData.labels[0]&lt;br /&gt;
    Move &amp;quot;Februari&amp;quot;     to tData.labels[1]&lt;br /&gt;
    Move &amp;quot;#FF0000&amp;quot;      to tData.datasets[0].strokeColor&lt;br /&gt;
    Move 55             to tData.datasets[0].data[0]&lt;br /&gt;
    Move 88             to tData.datasets[0].data[0]&lt;br /&gt;
     &lt;br /&gt;
    //  Call the client action&lt;br /&gt;
    Send ClientAction &amp;quot;processData2&amp;quot; aParams tData&lt;br /&gt;
End_Procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
//  Client action called with action data&lt;br /&gt;
processData2 : function(){&lt;br /&gt;
    var tData;&lt;br /&gt;
    &lt;br /&gt;
    // Retrieve value tree and deserialize&lt;br /&gt;
    tData = this._tActionData;&lt;br /&gt;
    &lt;br /&gt;
    // Do something with the data&lt;br /&gt;
    alert(tData.datasets[0].strokeColor);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that ClientAction takes a variant parameter that it serializes to JSON. Both API&#039;s are backwards compatible so working with tWebValueTree still works. The value tree&#039;s are also still used for client web properties.&lt;br /&gt;
&lt;br /&gt;
[[Category: Web Applications]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Using_cWebHttpHandler_with_JSON_instead_of_tWebValueTree&amp;diff=3667</id>
		<title>Using cWebHttpHandler with JSON instead of tWebValueTree</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Using_cWebHttpHandler_with_JSON_instead_of_tWebValueTree&amp;diff=3667"/>
		<updated>2023-07-10T22:10:53Z</updated>

		<summary type="html">&lt;p&gt;Wil: formatting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;From this forum post: https://support.dataaccess.com/Forums/showthread.php?68231-ToDo-Describe-call-mode-and-a-few-more-questions&amp;amp;p=371095#post371095&lt;br /&gt;
&lt;br /&gt;
Reposting it here so I can quickly find it next time I need it (sorry, not sorry)&lt;br /&gt;
&lt;br /&gt;
It is indeed true that for most situations the tWebValueTree is not needed any more. ClientActions and ServerActions can now use JSON Handles or structs &amp;amp; arrays that are directly serialized. So when calling a server action you can now do the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
//  Create data objects    &lt;br /&gt;
var oData =  {&lt;br /&gt;
    labels : [&amp;quot;January&amp;quot;,&amp;quot;February&amp;quot;,&amp;quot;March&amp;quot;,&amp;quot;April&amp;quot;,&amp;quot;May&amp;quot;,&amp;quot;June&amp;quot;,&amp;quot;July&amp;quot;],&lt;br /&gt;
    datasets : [{&lt;br /&gt;
        strokeColor : &amp;quot;rgba(220,220,220,1)&amp;quot;,&lt;br /&gt;
        data : [65,59,90,81,56,55,40]&lt;br /&gt;
    },{&lt;br /&gt;
        strokeColor : &amp;quot;rgba(151,187,205,1)&amp;quot;,&lt;br /&gt;
        data : [28,48,40,19,96,27,100]&lt;br /&gt;
    }]&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
//  Send call to the server&lt;br /&gt;
this.serverAction(&amp;quot;ProcessData2&amp;quot;, [ 2, 1 ], oData, function(oEvent){&lt;br /&gt;
    alert(oEvent.sReturnValue);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
//  Function called as server action&lt;br /&gt;
Function ProcessData2 Integer iParam1 Integer iParam2 Returns String&lt;br /&gt;
    tActionData tData&lt;br /&gt;
    Handle hoJson&lt;br /&gt;
    &lt;br /&gt;
    //  Retrieve and deserialize data&lt;br /&gt;
    Get phoActionJsonData to hoJson&lt;br /&gt;
    Get JsonToDataType of hoJson to tData&lt;br /&gt;
    &lt;br /&gt;
    Function_Return tData.labels[3]&lt;br /&gt;
End_Function&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So instead of ptActionData you use phoActionJsonData which gives a cJsonObject representing the data. Note that you do not have to cleanup this JSON Handle.&lt;br /&gt;
&lt;br /&gt;
For client actions you can do the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
Procedure ProcessDataOnClient2&lt;br /&gt;
    //  Send the client action&lt;br /&gt;
    String[] aParams&lt;br /&gt;
    tActionData tData&lt;br /&gt;
     &lt;br /&gt;
    //  Generate some data&lt;br /&gt;
    Move &amp;quot;Januari&amp;quot;      to tData.labels[0]&lt;br /&gt;
    Move &amp;quot;Februari&amp;quot;     to tData.labels[1]&lt;br /&gt;
    Move &amp;quot;#FF0000&amp;quot;      to tData.datasets[0].strokeColor&lt;br /&gt;
    Move 55             to tData.datasets[0].data[0]&lt;br /&gt;
    Move 88             to tData.datasets[0].data[0]&lt;br /&gt;
     &lt;br /&gt;
    //  Call the client action&lt;br /&gt;
    Send ClientAction &amp;quot;processData2&amp;quot; aParams tData&lt;br /&gt;
End_Procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
//  Client action called with action data&lt;br /&gt;
processData2 : function(){&lt;br /&gt;
    var tData;&lt;br /&gt;
    &lt;br /&gt;
    // Retrieve value tree and deserialize&lt;br /&gt;
    tData = this._tActionData;&lt;br /&gt;
    &lt;br /&gt;
    // Do something with the data&lt;br /&gt;
    alert(tData.datasets[0].strokeColor);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that ClientAction takes a variant parameter that it serializes to JSON. Both API&#039;s are backwards compatible so working with tWebValueTree still works. The value tree&#039;s are also still used for client web properties.&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Using_cWebHttpHandler_with_JSON_instead_of_tWebValueTree&amp;diff=3666</id>
		<title>Using cWebHttpHandler with JSON instead of tWebValueTree</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Using_cWebHttpHandler_with_JSON_instead_of_tWebValueTree&amp;diff=3666"/>
		<updated>2023-07-10T22:07:58Z</updated>

		<summary type="html">&lt;p&gt;Wil: Created page with &amp;quot;From this forum post: https://support.dataaccess.com/Forums/showthread.php?68231-ToDo-Describe-call-mode-and-a-few-more-questions&amp;amp;p=371095#post371095  Reposting it here so I can quickly find it next time I need it (sorry, not sorry)  It is indeed true that for most situations the tWebValueTree is not needed any more. ClientActions and ServerActions can now use JSON Handles or structs &amp;amp; arrays that are directly serialized. So when calling a server action you can now do th...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;From this forum post: https://support.dataaccess.com/Forums/showthread.php?68231-ToDo-Describe-call-mode-and-a-few-more-questions&amp;amp;p=371095#post371095&lt;br /&gt;
&lt;br /&gt;
Reposting it here so I can quickly find it next time I need it (sorry, not sorry)&lt;br /&gt;
&lt;br /&gt;
It is indeed true that for most situations the tWebValueTree is not needed any more. ClientActions and ServerActions can now use JSON Handles or structs &amp;amp; arrays that are directly serialized. So when calling a server action you can now do the following:&lt;br /&gt;
Code:&lt;br /&gt;
&lt;br /&gt;
//  Create data objects    &lt;br /&gt;
var oData =  {&lt;br /&gt;
    labels : [&amp;quot;January&amp;quot;,&amp;quot;February&amp;quot;,&amp;quot;March&amp;quot;,&amp;quot;April&amp;quot;,&amp;quot;May&amp;quot;,&amp;quot;June&amp;quot;,&amp;quot;July&amp;quot;],&lt;br /&gt;
    datasets : [{&lt;br /&gt;
        strokeColor : &amp;quot;rgba(220,220,220,1)&amp;quot;,&lt;br /&gt;
        data : [65,59,90,81,56,55,40]&lt;br /&gt;
    },{&lt;br /&gt;
        strokeColor : &amp;quot;rgba(151,187,205,1)&amp;quot;,&lt;br /&gt;
        data : [28,48,40,19,96,27,100]&lt;br /&gt;
    }]&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
//  Send call to the server&lt;br /&gt;
this.serverAction(&amp;quot;ProcessData2&amp;quot;, [ 2, 1 ], oData, function(oEvent){&lt;br /&gt;
    alert(oEvent.sReturnValue);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&lt;br /&gt;
//  Function called as server action&lt;br /&gt;
Function ProcessData2 Integer iParam1 Integer iParam2 Returns String&lt;br /&gt;
    tActionData tData&lt;br /&gt;
    Handle hoJson&lt;br /&gt;
    &lt;br /&gt;
    //  Retrieve and deserialize data&lt;br /&gt;
    Get phoActionJsonData to hoJson&lt;br /&gt;
    Get JsonToDataType of hoJson to tData&lt;br /&gt;
    &lt;br /&gt;
    Function_Return tData.labels[3]&lt;br /&gt;
End_Function&lt;br /&gt;
&lt;br /&gt;
So instead of ptActionData you use phoActionJsonData which gives a cJsonObject representing the data. Note that you do not have to cleanup this JSON Handle.&lt;br /&gt;
&lt;br /&gt;
For client actions you can do the following:&lt;br /&gt;
Code:&lt;br /&gt;
&lt;br /&gt;
Procedure ProcessDataOnClient2&lt;br /&gt;
    //  Send the client action&lt;br /&gt;
    String[] aParams&lt;br /&gt;
    tActionData tData&lt;br /&gt;
     &lt;br /&gt;
    //  Generate some data&lt;br /&gt;
    Move &amp;quot;Januari&amp;quot;      to tData.labels[0]&lt;br /&gt;
    Move &amp;quot;Februari&amp;quot;     to tData.labels[1]&lt;br /&gt;
    Move &amp;quot;#FF0000&amp;quot;      to tData.datasets[0].strokeColor&lt;br /&gt;
    Move 55             to tData.datasets[0].data[0]&lt;br /&gt;
    Move 88             to tData.datasets[0].data[0]&lt;br /&gt;
     &lt;br /&gt;
    //  Call the client action&lt;br /&gt;
    Send ClientAction &amp;quot;processData2&amp;quot; aParams tData&lt;br /&gt;
End_Procedure&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&lt;br /&gt;
//  Client action called with action data&lt;br /&gt;
processData2 : function(){&lt;br /&gt;
    var tData;&lt;br /&gt;
    &lt;br /&gt;
    // Retrieve value tree and deserialize&lt;br /&gt;
    tData = this._tActionData;&lt;br /&gt;
    &lt;br /&gt;
    // Do something with the data&lt;br /&gt;
    alert(tData.datasets[0].strokeColor);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Note that ClientAction takes a variant parameter that it serializes to JSON. Both API&#039;s are backwards compatible so working with tWebValueTree still works. The value tree&#039;s are also still used for client web properties.&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=File_Comparison&amp;diff=3555</id>
		<title>File Comparison</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=File_Comparison&amp;diff=3555"/>
		<updated>2023-03-30T21:29:45Z</updated>

		<summary type="html">&lt;p&gt;Wil: /* Custom filters */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;File Comparison&#039;&#039;&#039; is the process of compare the difference between files.  Commonly this is used when merging source code with a [[Version Control]] file repository.&lt;br /&gt;
&lt;br /&gt;
==Why use File Comparison Software?==&lt;br /&gt;
When comparing source between different Visual DataFlex versions it is a HUGE time saver to do this using source code compare tools.&lt;br /&gt;
Below is a few rules one can use to compare sources between VDF11.1 and VDF12.1&lt;br /&gt;
&lt;br /&gt;
The tips below are for a product called &#039;&#039;&#039;Beyond Compare&#039;&#039;&#039;, but i&#039;m sure your product will do fine too. If you are not using a product for this then GO BUY ONE! it is the best investment you can make EVER.&lt;br /&gt;
&lt;br /&gt;
==File Comparison software==&lt;br /&gt;
There are many different file comparison tools out there, the most commonly used being &#039;&#039;&#039;Beyond Compare&#039;&#039;&#039;.  Other alternatives for Windows include Araxis merge, WinDiff and Winmerge.&lt;br /&gt;
&lt;br /&gt;
For [[Linux]] users there is Meld.&lt;br /&gt;
&lt;br /&gt;
For a comparison of file comparison tools visit [http://en.wikipedia.org/wiki/Comparison_of_file_comparison_tools Wikipedia]. &lt;br /&gt;
&lt;br /&gt;
==Beyond Compare==&lt;br /&gt;
Beyond Compare is a commonly used File Comparison tool developed by Scooter Software.&lt;br /&gt;
&lt;br /&gt;
=== How-to set up Beyond Compare ===&lt;br /&gt;
&lt;br /&gt;
==== Configure File Formats ====&lt;br /&gt;
&lt;br /&gt;
In order to have Beyond Compare recognize DataFlex based on File Type, you can add the following after starting the main program.&lt;br /&gt;
Main menu -&amp;gt; Tools -&amp;gt; File Formats -&amp;gt; Press the &amp;quot;+&amp;quot; button to add a new file format --&amp;gt; Text Format&lt;br /&gt;
&lt;br /&gt;
General tab&lt;br /&gt;
 Mask: *.src;*.pkg;*.dg;*.vw;*.dd;*.sl;*.ddo;*.rv;*.tt?;*.wo;*.utl;*.nui&lt;br /&gt;
 Description: - Compares DataFlex source.&lt;br /&gt;
&lt;br /&gt;
Save As: DataFlex Source&lt;br /&gt;
&lt;br /&gt;
==== Configure per session ==== &lt;br /&gt;
In order to change the rules on how BC compares, you should go into compare source mode --&amp;gt; compare two source files --&amp;gt; and then click on the &amp;quot;guy with the cap&amp;quot; in the toolbar&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; General Tab Page &#039;&#039;&#039;&lt;br /&gt;
 Name : DataFlex&lt;br /&gt;
 Associated with: *.src;*.pkg;*.dg;*.vw;*.dd;*.sl;*.ddo;*.rv;*.tt?;*.wo;*.utl;*.nui&lt;br /&gt;
&lt;br /&gt;
 x Whitespace includes TABS and spaces&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; Importance Tab Page &#039;&#039;&#039;&lt;br /&gt;
 Unimportant text group &amp;gt;&amp;gt; put a check in all of the checkboxes&lt;br /&gt;
 This is also the place where you can add custom rules/filters&lt;br /&gt;
&lt;br /&gt;
=== Custom filters ===&lt;br /&gt;
1. Ignore differences in comments.&lt;br /&gt;
 Click on New, Category Delimited&lt;br /&gt;
 Beginning with: //&lt;br /&gt;
 Check &amp;quot;stopping at end of line&amp;quot;&lt;br /&gt;
&lt;br /&gt;
2. Ignore new metadata markup&lt;br /&gt;
 Click on New, Category Delimited&lt;br /&gt;
 Beginning with: {&lt;br /&gt;
 and ending with: }&lt;br /&gt;
&lt;br /&gt;
3. Ignore &amp;quot;current_object&amp;quot; vs &amp;quot;self&amp;quot; syntax&lt;br /&gt;
 Click on Regular expressions&lt;br /&gt;
  (?i).*current_object.*|.*self.*&lt;br /&gt;
&lt;br /&gt;
4. Ignore difference between writing &amp;quot;Use foo&amp;quot; and &amp;quot;Use foo.pkg&amp;quot;&lt;br /&gt;
 Click on Regular expressions&lt;br /&gt;
 (?i)^\s*use\s+.*|^\s*use.*\.pkg&lt;br /&gt;
&lt;br /&gt;
5. Ignore changed writing style for constants: C$_FOO vs C_$FOO&lt;br /&gt;
 Click on Regular expressions&lt;br /&gt;
 (?i)\s+C\$_.*|\s+C_\$.*&lt;br /&gt;
&lt;br /&gt;
6. Ignore &amp;quot;string&amp;quot; vs. &amp;quot;local string&amp;quot;&lt;br /&gt;
 Click on Regular expressions&lt;br /&gt;
  (?i)^\s*local\s+string.*|^\s*string.*&lt;br /&gt;
 Replace string with date / integer / number to filter other similar code.&lt;br /&gt;
&lt;br /&gt;
7. Ignore meta tag documentation changes between 12.1 and 2008&lt;br /&gt;
 Click on Regular expressions&lt;br /&gt;
  (?i)\s*\/\/Doc\/.*|\s*\{.*&lt;br /&gt;
&lt;br /&gt;
8. Ignore the public keyword in property declarations&lt;br /&gt;
 Click on Regular expressions&lt;br /&gt;
  (?i)^\s*property\s+integer.*public.*|^\s*property\s+integer.*&lt;br /&gt;
 Repeat the same for the other datatypes&lt;br /&gt;
&lt;br /&gt;
9. Comment vs. No comments&lt;br /&gt;
 Click On Regex&lt;br /&gt;
  (?i)^\s*\/\/.*|^\s*&lt;br /&gt;
&lt;br /&gt;
10. Use statement vs missing Use statement&lt;br /&gt;
 As before a regular expression&lt;br /&gt;
  (?i)^\s*Use.*\.pkg|^\s*&lt;br /&gt;
&lt;br /&gt;
11. Ignore removed comments after End_Object,End_Class,End_Function,End_Procedure&lt;br /&gt;
 Using a regular expressions&lt;br /&gt;
  (?i)\s*end.*\/\/.*|\s*end.*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
PS: Begin this year I was promised by Scootersoftware Support that they would implement a way to enable/disable filters on a per filter bases in the next revision of the tool. &amp;lt;--- I wrote that in 2008! This was implemented by using sessions. You can create different sessions with different filters.&lt;br /&gt;
&lt;br /&gt;
==Winmerge==&lt;br /&gt;
Winmerge is an [[Open Source]] file comparison tool.&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
*[http://www.scootersoftware.com/ Beyond Compare]&lt;br /&gt;
*[http://winmerge.org/ Winmerge]&lt;br /&gt;
*[http://www.araxis.com/ Araxis]&lt;br /&gt;
&lt;br /&gt;
[[Category:Development Tools]]&lt;br /&gt;
[[Category: Version Control]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=File_Comparison&amp;diff=3554</id>
		<title>File Comparison</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=File_Comparison&amp;diff=3554"/>
		<updated>2023-03-30T21:25:39Z</updated>

		<summary type="html">&lt;p&gt;Wil: Some minor updates for Beyond Compare version 4.x&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;File Comparison&#039;&#039;&#039; is the process of compare the difference between files.  Commonly this is used when merging source code with a [[Version Control]] file repository.&lt;br /&gt;
&lt;br /&gt;
==Why use File Comparison Software?==&lt;br /&gt;
When comparing source between different Visual DataFlex versions it is a HUGE time saver to do this using source code compare tools.&lt;br /&gt;
Below is a few rules one can use to compare sources between VDF11.1 and VDF12.1&lt;br /&gt;
&lt;br /&gt;
The tips below are for a product called &#039;&#039;&#039;Beyond Compare&#039;&#039;&#039;, but i&#039;m sure your product will do fine too. If you are not using a product for this then GO BUY ONE! it is the best investment you can make EVER.&lt;br /&gt;
&lt;br /&gt;
==File Comparison software==&lt;br /&gt;
There are many different file comparison tools out there, the most commonly used being &#039;&#039;&#039;Beyond Compare&#039;&#039;&#039;.  Other alternatives for Windows include Araxis merge, WinDiff and Winmerge.&lt;br /&gt;
&lt;br /&gt;
For [[Linux]] users there is Meld.&lt;br /&gt;
&lt;br /&gt;
For a comparison of file comparison tools visit [http://en.wikipedia.org/wiki/Comparison_of_file_comparison_tools Wikipedia]. &lt;br /&gt;
&lt;br /&gt;
==Beyond Compare==&lt;br /&gt;
Beyond Compare is a commonly used File Comparison tool developed by Scooter Software.&lt;br /&gt;
&lt;br /&gt;
=== How-to set up Beyond Compare ===&lt;br /&gt;
&lt;br /&gt;
==== Configure File Formats ====&lt;br /&gt;
&lt;br /&gt;
In order to have Beyond Compare recognize DataFlex based on File Type, you can add the following after starting the main program.&lt;br /&gt;
Main menu -&amp;gt; Tools -&amp;gt; File Formats -&amp;gt; Press the &amp;quot;+&amp;quot; button to add a new file format --&amp;gt; Text Format&lt;br /&gt;
&lt;br /&gt;
General tab&lt;br /&gt;
 Mask: *.src;*.pkg;*.dg;*.vw;*.dd;*.sl;*.ddo;*.rv;*.tt?;*.wo;*.utl;*.nui&lt;br /&gt;
 Description: - Compares DataFlex source.&lt;br /&gt;
&lt;br /&gt;
Save As: DataFlex Source&lt;br /&gt;
&lt;br /&gt;
==== Configure per session ==== &lt;br /&gt;
In order to change the rules on how BC compares, you should go into compare source mode --&amp;gt; compare two source files --&amp;gt; and then click on the &amp;quot;guy with the cap&amp;quot; in the toolbar&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; General Tab Page &#039;&#039;&#039;&lt;br /&gt;
 Name : DataFlex&lt;br /&gt;
 Associated with: *.src;*.pkg;*.dg;*.vw;*.dd;*.sl;*.ddo;*.rv;*.tt?;*.wo;*.utl;*.nui&lt;br /&gt;
&lt;br /&gt;
 x Whitespace includes TABS and spaces&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; Importance Tab Page &#039;&#039;&#039;&lt;br /&gt;
 Unimportant text group &amp;gt;&amp;gt; put a check in all of the checkboxes&lt;br /&gt;
 This is also the place where you can add custom rules/filters&lt;br /&gt;
&lt;br /&gt;
=== Custom filters ===&lt;br /&gt;
1. Ignore differences in comments.&lt;br /&gt;
 Click on New, Category Delimited&lt;br /&gt;
 Beginning with: //&lt;br /&gt;
 Check &amp;quot;stopping at end of line&amp;quot;&lt;br /&gt;
&lt;br /&gt;
2. Ignore new metadata markup&lt;br /&gt;
 Click on New, Category Delimited&lt;br /&gt;
 Beginning with: {&lt;br /&gt;
 and ending with: }&lt;br /&gt;
&lt;br /&gt;
3. Ignore &amp;quot;current_object&amp;quot; vs &amp;quot;self&amp;quot; syntax&lt;br /&gt;
 Click on Regular expressions&lt;br /&gt;
  (?i).*current_object.*|.*self.*&lt;br /&gt;
&lt;br /&gt;
4. Ignore difference between writing &amp;quot;Use foo&amp;quot; and &amp;quot;Use foo.pkg&amp;quot;&lt;br /&gt;
 Click on Regular expressions&lt;br /&gt;
 (?i)^\s*use\s+.*|^\s*use.*\.pkg&lt;br /&gt;
&lt;br /&gt;
5. Ignore changed writing style for constants: C$_FOO vs C_$FOO&lt;br /&gt;
 Click on Regular expressions&lt;br /&gt;
 (?i)\s+C\$_.*|\s+C_\$.*&lt;br /&gt;
&lt;br /&gt;
6. Ignore &amp;quot;string&amp;quot; vs. &amp;quot;local string&amp;quot;&lt;br /&gt;
 Click on Regular expressions&lt;br /&gt;
  (?i)^\s*local\s+string.*|^\s*string.*&lt;br /&gt;
 Replace string with date / integer / number to filter other similar code.&lt;br /&gt;
&lt;br /&gt;
7. Ignore meta tag documentation changes between 12.1 and 2008&lt;br /&gt;
 Click on Regular expressions&lt;br /&gt;
  (?i)\s*\/\/Doc\/.*|\s*\{.*&lt;br /&gt;
&lt;br /&gt;
8. Ignore the public keyword in property declarations&lt;br /&gt;
 Click on Regular expressions&lt;br /&gt;
  (?i)^\s*property\s+integer.*public.*|^\s*property\s+integer.*&lt;br /&gt;
 Repeat the same for the other datatypes&lt;br /&gt;
&lt;br /&gt;
9. Comment vs. No comments&lt;br /&gt;
 Click On Regex&lt;br /&gt;
  (?i)^\s*\/\/.*|^\s*&lt;br /&gt;
&lt;br /&gt;
10. Use statement vs missing Use statement&lt;br /&gt;
 As before a regular expression&lt;br /&gt;
  (?i)^\s*Use.*\.pkg|^\s*&lt;br /&gt;
&lt;br /&gt;
11. Ignore removed comments after End_Object,End_Class,End_Function,End_Procedure&lt;br /&gt;
 Using a regular expressions&lt;br /&gt;
  (?i)\s*end.*\/\/.*|\s*end.*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
PS: Begin this year I was promised by Scootersoftware Support that they would implement a way to enable/disable filters on a per filter bases in the next revision of the tool.&lt;br /&gt;
&lt;br /&gt;
==Winmerge==&lt;br /&gt;
Winmerge is an [[Open Source]] file comparison tool.&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
*[http://www.scootersoftware.com/ Beyond Compare]&lt;br /&gt;
*[http://winmerge.org/ Winmerge]&lt;br /&gt;
*[http://www.araxis.com/ Araxis]&lt;br /&gt;
&lt;br /&gt;
[[Category:Development Tools]]&lt;br /&gt;
[[Category: Version Control]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=DateTime_functions&amp;diff=3553</id>
		<title>DateTime functions</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=DateTime_functions&amp;diff=3553"/>
		<updated>2023-03-16T10:55:38Z</updated>

		<summary type="html">&lt;p&gt;Wil: Moved external links section to the bottom&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== ISO8601TimeStamp ===&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a function I use for creating a timestamp, this uses the ISO8601 format as it has advantages such as that it automatically sorts correctly when sorted with ASCII ordering.&lt;br /&gt;
&lt;br /&gt;
This works well even with databases - such as the embedded database - that do not offer native date time formats.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  //&lt;br /&gt;
  // Returns an ISO8601 timestamp this is used by for example SQLite in date time columns and works&lt;br /&gt;
  // wonderfully well within the dataflex database too.&lt;br /&gt;
  // You&#039;ll need an ascii column of 24 characters&lt;br /&gt;
  // the format is:&lt;br /&gt;
  // YYYY-MM-DDTHH:MM:SS.SSS&lt;br /&gt;
  // This is assuming you do not need timezone information.&lt;br /&gt;
  // See also:&lt;br /&gt;
  // http://www.sqlite.org/lang_datefunc.html&lt;br /&gt;
  //&lt;br /&gt;
  Function ISO8601TimeStamp Returns String&lt;br /&gt;
    String    sYear&lt;br /&gt;
    String    sMonth&lt;br /&gt;
    String    sDay&lt;br /&gt;
    String    sHour&lt;br /&gt;
    String    sMin&lt;br /&gt;
    String    sSec&lt;br /&gt;
    String    smilSec&lt;br /&gt;
    String    sTimeStamp&lt;br /&gt;
    DateTime  dtNow&lt;br /&gt;
    &lt;br /&gt;
    Move (CurrentDateTime())    to dtNow&lt;br /&gt;
    Move (DateGetYear(dtNow))        to sYear&lt;br /&gt;
    Move (DateGetMonth(dtNow))       to sMonth&lt;br /&gt;
    Move (DateGetDay(dtNow))         to sDay&lt;br /&gt;
    Move (DateGetHour(dtNow))        to sHour&lt;br /&gt;
    Move (DateGetMinute(dtNow))      to sMin&lt;br /&gt;
    Move (DateGetSecond(dtNow))      to sSec&lt;br /&gt;
    Move (DateGetMillisecond(dtNow)) to smilSec&lt;br /&gt;
    &lt;br /&gt;
    If (Length(sMonth)=1)  Move (&amp;quot;0&amp;quot;+sMonth)  to sMonth&lt;br /&gt;
    If (Length(sDay)=1)    Move (&amp;quot;0&amp;quot;+sDay)    to sDay&lt;br /&gt;
    If (Length(sHour)=1)   Move (&amp;quot;0&amp;quot;+sHour)   to sHour&lt;br /&gt;
    If (Length(sMin)=1)    Move (&amp;quot;0&amp;quot;+sMin)    to sMin&lt;br /&gt;
    If (Length(sSec)=1)    Move (&amp;quot;0&amp;quot;+sSec)    to sSec&lt;br /&gt;
    If (Length(smilSec)=1) Move (&amp;quot;0&amp;quot;+smilSec) to smilSec&lt;br /&gt;
    If (Length(smilSec)=2) Move (&amp;quot;0&amp;quot;+smilSec) to smilSec&lt;br /&gt;
    &lt;br /&gt;
    Move (SFormat(&amp;quot;%1-%2-%3T%4:%5:%6.%7&amp;quot;,sYear,sMonth,sDay,sHour,sMin,sSec,smilSec)) to sTimeStamp&lt;br /&gt;
    &lt;br /&gt;
    Function_Return sTimeStamp&lt;br /&gt;
  End_Function&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== XML DateTime functions ===&lt;br /&gt;
&lt;br /&gt;
If you have a SOAP service and you need to convert from / to datetime formats then these functions might come in handy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //  Gets the data and time for the datetime string as passed by&lt;br /&gt;
    //  XML. Automatic casting strips of the time part and we do&lt;br /&gt;
    //  want the time&lt;br /&gt;
    //&lt;br /&gt;
    //  Returns:&lt;br /&gt;
    //      dtDateTime with the date and time as passed in xml&lt;br /&gt;
    //&lt;br /&gt;
    Function StringToDateTime String sDateTime Returns DateTime&lt;br /&gt;
        String sDate&lt;br /&gt;
        String sYear sMonth sDay&lt;br /&gt;
        String sHours sMinutes sSeconds&lt;br /&gt;
        String sMilliSeconds&lt;br /&gt;
        String sTimeString&lt;br /&gt;
        Integer iPos&lt;br /&gt;
        DateTime dtTime&lt;br /&gt;
        &lt;br /&gt;
        Move &amp;quot;&amp;quot; to sTimeString&lt;br /&gt;
        Move (Pos(&amp;quot;T&amp;quot;,sDateTime)) to iPos&lt;br /&gt;
        If (iPos&amp;gt;0) Begin&lt;br /&gt;
          Move (Left(sDateTime,iPos-1)) to sDate&lt;br /&gt;
          Move (Left(sDate,4))  to sYear&lt;br /&gt;
          Move (Mid(sDate,2,6)) to sMonth&lt;br /&gt;
          Move (Right(sDate,2)) to sDay&lt;br /&gt;
          //Move sDate to dtTime // does not work, because US has no military date format&lt;br /&gt;
          Move (Replace(sDate+&amp;quot;T&amp;quot;,sDateTime,&amp;quot;&amp;quot;)) to sTimeString&lt;br /&gt;
          //  Extract parts&lt;br /&gt;
          Move (Mid(sTimeString, 2, 1))  to sHours&lt;br /&gt;
          Move (Mid(sTimeString, 2, 4))  to sMinutes&lt;br /&gt;
          Move (Mid(sTimeString, 2, 7))  to sSeconds&lt;br /&gt;
          Move (Mid(sTimeString, 3, 10)) to sMilliSeconds&lt;br /&gt;
        End&lt;br /&gt;
        &lt;br /&gt;
        //  Set to DateTime&lt;br /&gt;
        Move (DateSetYear(dtTime,      Integer(sYear)))    to dtTime&lt;br /&gt;
        Move (DateSetMonth(dtTime,     Integer(sMonth)))   to dtTime&lt;br /&gt;
        Move (DateSetDay(dtTime,       Integer(sDay)))     to dtTime&lt;br /&gt;
        Move (DateSetHour(dtTime,      Integer(sHours)))   to dtTime&lt;br /&gt;
        Move (DateSetMinute(dtTime,    Integer(sMinutes))) to dtTime&lt;br /&gt;
        Move (DateSetSecond(dtTime,    Integer(sSeconds))) to dtTime&lt;br /&gt;
        Move (DateSetMilliSecond(dtTime, Integer(sMilliSeconds))) to dtTime&lt;br /&gt;
        &lt;br /&gt;
        Function_Return dtTime&lt;br /&gt;
    End_Function&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //  Gets the datetime as passed by XML.&lt;br /&gt;
    //  Automatic casting strips of the Time part and we do&lt;br /&gt;
    //  want the time&lt;br /&gt;
    //&lt;br /&gt;
    //  Returns:&lt;br /&gt;
    //      DateTime string with the date and time as passed in xml&lt;br /&gt;
    //&lt;br /&gt;
    Function DateTimeToString DateTime dtTime Returns String&lt;br /&gt;
        String sYear sMonth sDay&lt;br /&gt;
        String sHours sMinutes sSeconds&lt;br /&gt;
        String sMilliSeconds&lt;br /&gt;
        String sTimeString&lt;br /&gt;
        &lt;br /&gt;
        Move &amp;quot;&amp;quot; to sTimeString&lt;br /&gt;
        &lt;br /&gt;
        Move (DateGetYear(dtTime))        to sYear&lt;br /&gt;
        Move (DateGetMonth(dtTime))       to sMonth&lt;br /&gt;
        If (Integer(sMonth)&amp;lt;10) Move (&amp;quot;0&amp;quot;+sMonth) to sMonth&lt;br /&gt;
        Move (DateGetDay(dtTime))         to sDay&lt;br /&gt;
        If (Integer(sDay)&amp;lt;10)   Move (&amp;quot;0&amp;quot;+sDay) to sDay&lt;br /&gt;
        Move (DateGetHour(dtTime))        to sHours&lt;br /&gt;
        If (Integer(sHours)&amp;lt;10) Move (&amp;quot;0&amp;quot;+sHours) to sHours&lt;br /&gt;
        Move (DateGetMinute(dtTime))      to sMinutes&lt;br /&gt;
        If (Integer(sMinutes)&amp;lt;10) Move (&amp;quot;0&amp;quot;+sMinutes) to sMinutes&lt;br /&gt;
        Move (DateGetSecond(dtTime))      to sSeconds&lt;br /&gt;
        If (Integer(sSeconds)&amp;lt;10) Move (&amp;quot;0&amp;quot;+sSeconds) to sSeconds&lt;br /&gt;
        Move (DateGetMilliSecond(dtTime)) to sMilliSeconds&lt;br /&gt;
        Move (sYear+&amp;quot;-&amp;quot;+sMonth+&amp;quot;-&amp;quot;+sDay+&amp;quot;T&amp;quot;+sHours+&amp;quot;:&amp;quot;+sMinutes+&amp;quot;:&amp;quot;+sSeconds+&amp;quot;.&amp;quot;+sMilliSeconds) to sTimeString&lt;br /&gt;
        Function_Return sTimeString&lt;br /&gt;
    End_Function&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== External links ===&lt;br /&gt;
&lt;br /&gt;
See also:&lt;br /&gt;
* [https://downloads.dataaccess.com/downloads/dataflex/date-time-1467#description DataAccess DateTime Library]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:How To]]&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=DateTime_functions&amp;diff=3552</id>
		<title>DateTime functions</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=DateTime_functions&amp;diff=3552"/>
		<updated>2023-03-16T10:54:44Z</updated>

		<summary type="html">&lt;p&gt;Wil: /* ISO8601TimeStamp */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== ISO8601TimeStamp ===&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a function I use for creating a timestamp, this uses the ISO8601 format as it has advantages such as that it automatically sorts correctly when sorted with ASCII ordering.&lt;br /&gt;
&lt;br /&gt;
This works well even with databases - such as the embedded database - that do not offer native date time formats.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  //&lt;br /&gt;
  // Returns an ISO8601 timestamp this is used by for example SQLite in date time columns and works&lt;br /&gt;
  // wonderfully well within the dataflex database too.&lt;br /&gt;
  // You&#039;ll need an ascii column of 24 characters&lt;br /&gt;
  // the format is:&lt;br /&gt;
  // YYYY-MM-DDTHH:MM:SS.SSS&lt;br /&gt;
  // This is assuming you do not need timezone information.&lt;br /&gt;
  // See also:&lt;br /&gt;
  // http://www.sqlite.org/lang_datefunc.html&lt;br /&gt;
  //&lt;br /&gt;
  Function ISO8601TimeStamp Returns String&lt;br /&gt;
    String    sYear&lt;br /&gt;
    String    sMonth&lt;br /&gt;
    String    sDay&lt;br /&gt;
    String    sHour&lt;br /&gt;
    String    sMin&lt;br /&gt;
    String    sSec&lt;br /&gt;
    String    smilSec&lt;br /&gt;
    String    sTimeStamp&lt;br /&gt;
    DateTime  dtNow&lt;br /&gt;
    &lt;br /&gt;
    Move (CurrentDateTime())    to dtNow&lt;br /&gt;
    Move (DateGetYear(dtNow))        to sYear&lt;br /&gt;
    Move (DateGetMonth(dtNow))       to sMonth&lt;br /&gt;
    Move (DateGetDay(dtNow))         to sDay&lt;br /&gt;
    Move (DateGetHour(dtNow))        to sHour&lt;br /&gt;
    Move (DateGetMinute(dtNow))      to sMin&lt;br /&gt;
    Move (DateGetSecond(dtNow))      to sSec&lt;br /&gt;
    Move (DateGetMillisecond(dtNow)) to smilSec&lt;br /&gt;
    &lt;br /&gt;
    If (Length(sMonth)=1)  Move (&amp;quot;0&amp;quot;+sMonth)  to sMonth&lt;br /&gt;
    If (Length(sDay)=1)    Move (&amp;quot;0&amp;quot;+sDay)    to sDay&lt;br /&gt;
    If (Length(sHour)=1)   Move (&amp;quot;0&amp;quot;+sHour)   to sHour&lt;br /&gt;
    If (Length(sMin)=1)    Move (&amp;quot;0&amp;quot;+sMin)    to sMin&lt;br /&gt;
    If (Length(sSec)=1)    Move (&amp;quot;0&amp;quot;+sSec)    to sSec&lt;br /&gt;
    If (Length(smilSec)=1) Move (&amp;quot;0&amp;quot;+smilSec) to smilSec&lt;br /&gt;
    If (Length(smilSec)=2) Move (&amp;quot;0&amp;quot;+smilSec) to smilSec&lt;br /&gt;
    &lt;br /&gt;
    Move (SFormat(&amp;quot;%1-%2-%3T%4:%5:%6.%7&amp;quot;,sYear,sMonth,sDay,sHour,sMin,sSec,smilSec)) to sTimeStamp&lt;br /&gt;
    &lt;br /&gt;
    Function_Return sTimeStamp&lt;br /&gt;
  End_Function&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== External links ===&lt;br /&gt;
&lt;br /&gt;
See also:&lt;br /&gt;
* [https://downloads.dataaccess.com/downloads/dataflex/date-time-1467#description DataAccess DateTime Library]&lt;br /&gt;
&lt;br /&gt;
=== XML DateTime functions ===&lt;br /&gt;
&lt;br /&gt;
If you have a SOAP service and you need to convert from / to datetime formats then these functions might come in handy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //  Gets the data and time for the datetime string as passed by&lt;br /&gt;
    //  XML. Automatic casting strips of the time part and we do&lt;br /&gt;
    //  want the time&lt;br /&gt;
    //&lt;br /&gt;
    //  Returns:&lt;br /&gt;
    //      dtDateTime with the date and time as passed in xml&lt;br /&gt;
    //&lt;br /&gt;
    Function StringToDateTime String sDateTime Returns DateTime&lt;br /&gt;
        String sDate&lt;br /&gt;
        String sYear sMonth sDay&lt;br /&gt;
        String sHours sMinutes sSeconds&lt;br /&gt;
        String sMilliSeconds&lt;br /&gt;
        String sTimeString&lt;br /&gt;
        Integer iPos&lt;br /&gt;
        DateTime dtTime&lt;br /&gt;
        &lt;br /&gt;
        Move &amp;quot;&amp;quot; to sTimeString&lt;br /&gt;
        Move (Pos(&amp;quot;T&amp;quot;,sDateTime)) to iPos&lt;br /&gt;
        If (iPos&amp;gt;0) Begin&lt;br /&gt;
          Move (Left(sDateTime,iPos-1)) to sDate&lt;br /&gt;
          Move (Left(sDate,4))  to sYear&lt;br /&gt;
          Move (Mid(sDate,2,6)) to sMonth&lt;br /&gt;
          Move (Right(sDate,2)) to sDay&lt;br /&gt;
          //Move sDate to dtTime // does not work, because US has no military date format&lt;br /&gt;
          Move (Replace(sDate+&amp;quot;T&amp;quot;,sDateTime,&amp;quot;&amp;quot;)) to sTimeString&lt;br /&gt;
          //  Extract parts&lt;br /&gt;
          Move (Mid(sTimeString, 2, 1))  to sHours&lt;br /&gt;
          Move (Mid(sTimeString, 2, 4))  to sMinutes&lt;br /&gt;
          Move (Mid(sTimeString, 2, 7))  to sSeconds&lt;br /&gt;
          Move (Mid(sTimeString, 3, 10)) to sMilliSeconds&lt;br /&gt;
        End&lt;br /&gt;
        &lt;br /&gt;
        //  Set to DateTime&lt;br /&gt;
        Move (DateSetYear(dtTime,      Integer(sYear)))    to dtTime&lt;br /&gt;
        Move (DateSetMonth(dtTime,     Integer(sMonth)))   to dtTime&lt;br /&gt;
        Move (DateSetDay(dtTime,       Integer(sDay)))     to dtTime&lt;br /&gt;
        Move (DateSetHour(dtTime,      Integer(sHours)))   to dtTime&lt;br /&gt;
        Move (DateSetMinute(dtTime,    Integer(sMinutes))) to dtTime&lt;br /&gt;
        Move (DateSetSecond(dtTime,    Integer(sSeconds))) to dtTime&lt;br /&gt;
        Move (DateSetMilliSecond(dtTime, Integer(sMilliSeconds))) to dtTime&lt;br /&gt;
        &lt;br /&gt;
        Function_Return dtTime&lt;br /&gt;
    End_Function&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    //&lt;br /&gt;
    //  Gets the datetime as passed by XML.&lt;br /&gt;
    //  Automatic casting strips of the Time part and we do&lt;br /&gt;
    //  want the time&lt;br /&gt;
    //&lt;br /&gt;
    //  Returns:&lt;br /&gt;
    //      DateTime string with the date and time as passed in xml&lt;br /&gt;
    //&lt;br /&gt;
    Function DateTimeToString DateTime dtTime Returns String&lt;br /&gt;
        String sYear sMonth sDay&lt;br /&gt;
        String sHours sMinutes sSeconds&lt;br /&gt;
        String sMilliSeconds&lt;br /&gt;
        String sTimeString&lt;br /&gt;
        &lt;br /&gt;
        Move &amp;quot;&amp;quot; to sTimeString&lt;br /&gt;
        &lt;br /&gt;
        Move (DateGetYear(dtTime))        to sYear&lt;br /&gt;
        Move (DateGetMonth(dtTime))       to sMonth&lt;br /&gt;
        If (Integer(sMonth)&amp;lt;10) Move (&amp;quot;0&amp;quot;+sMonth) to sMonth&lt;br /&gt;
        Move (DateGetDay(dtTime))         to sDay&lt;br /&gt;
        If (Integer(sDay)&amp;lt;10)   Move (&amp;quot;0&amp;quot;+sDay) to sDay&lt;br /&gt;
        Move (DateGetHour(dtTime))        to sHours&lt;br /&gt;
        If (Integer(sHours)&amp;lt;10) Move (&amp;quot;0&amp;quot;+sHours) to sHours&lt;br /&gt;
        Move (DateGetMinute(dtTime))      to sMinutes&lt;br /&gt;
        If (Integer(sMinutes)&amp;lt;10) Move (&amp;quot;0&amp;quot;+sMinutes) to sMinutes&lt;br /&gt;
        Move (DateGetSecond(dtTime))      to sSeconds&lt;br /&gt;
        If (Integer(sSeconds)&amp;lt;10) Move (&amp;quot;0&amp;quot;+sSeconds) to sSeconds&lt;br /&gt;
        Move (DateGetMilliSecond(dtTime)) to sMilliSeconds&lt;br /&gt;
        Move (sYear+&amp;quot;-&amp;quot;+sMonth+&amp;quot;-&amp;quot;+sDay+&amp;quot;T&amp;quot;+sHours+&amp;quot;:&amp;quot;+sMinutes+&amp;quot;:&amp;quot;+sSeconds+&amp;quot;.&amp;quot;+sMilliSeconds) to sTimeString&lt;br /&gt;
        Function_Return sTimeString&lt;br /&gt;
    End_Function&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:How To]]&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=DfSplat&amp;diff=3551</id>
		<title>DfSplat</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=DfSplat&amp;diff=3551"/>
		<updated>2023-03-07T10:50:02Z</updated>

		<summary type="html">&lt;p&gt;Wil: Removing another really old one&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;dfSPlat&#039;&#039;&#039; is a free open source third party tool, intended to help with debugging DataFlex applications. It is written in DataFlex and wraps the DataFlex development components in order to run. At this moment it can be used to debug applications from Visual DataFlex 12.0 up to DataFlex 19.1&lt;br /&gt;
&lt;br /&gt;
==Random screenshots==&lt;br /&gt;
For context of these screenshots please see the following forum post. https://support.dataaccess.com/Forums/showthread.php?57177-VdfSplat-alfa-1-DataFlex-Debugger&amp;amp;p=299704#post299704&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDView2.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDView3.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDViewForeignTab.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDViewRelationshipsTab.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDViewViewTableTab.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-EvalObjects.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-EvalProperty.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-EvalPropertyOf.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-ObjectInspector.png]]&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
*This tool is currently (March 2020) in alpha stage.&lt;br /&gt;
&lt;br /&gt;
==Articles==&lt;br /&gt;
* [[Using dfSplat to identify object leaks]]&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
*[https://projects.vdf-guidance.com/projects/dfsplat dfSplat homepage]  &lt;br /&gt;
*[https://projects.vdf-guidance.com/projects/dfsplat/files dfSplat downloads]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Development Tools]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=DfSplat&amp;diff=3550</id>
		<title>DfSplat</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=DfSplat&amp;diff=3550"/>
		<updated>2023-03-07T10:48:36Z</updated>

		<summary type="html">&lt;p&gt;Wil: Removing another really old one&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;dfSPlat&#039;&#039;&#039; is a free open source third party tool, intended to help with debugging DataFlex applications. It is written in DataFlex and wraps the DataFlex development components in order to run. At this moment it can be used to debug applications from Visual DataFlex 12.0 up to DataFlex 19.1&lt;br /&gt;
&lt;br /&gt;
==Random screenshots==&lt;br /&gt;
For context of these screenshots please see the following forum post. https://support.dataaccess.com/Forums/showthread.php?57177-VdfSplat-alfa-1-DataFlex-Debugger&amp;amp;p=299704#post299704&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDView2.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDView3.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDView4.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDViewForeignTab.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDViewRelationshipsTab.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDViewViewTableTab.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-EvalObjects.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-EvalProperty.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-EvalPropertyOf.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-ObjectInspector.png]]&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
*This tool is currently (March 2020) in alpha stage.&lt;br /&gt;
&lt;br /&gt;
==Articles==&lt;br /&gt;
* [[Using dfSplat to identify object leaks]]&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
*[https://projects.vdf-guidance.com/projects/dfsplat dfSplat homepage]  &lt;br /&gt;
*[https://projects.vdf-guidance.com/projects/dfsplat/files dfSplat downloads]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Development Tools]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=DfSplat&amp;diff=3549</id>
		<title>DfSplat</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=DfSplat&amp;diff=3549"/>
		<updated>2023-03-07T10:46:01Z</updated>

		<summary type="html">&lt;p&gt;Wil: /* Random screenshots */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;dfSPlat&#039;&#039;&#039; is a free open source third party tool, intended to help with debugging DataFlex applications. It is written in DataFlex and wraps the DataFlex development components in order to run. At this moment it can be used to debug applications from Visual DataFlex 12.0 up to DataFlex 19.1&lt;br /&gt;
&lt;br /&gt;
==Random screenshots==&lt;br /&gt;
For context of these screenshots please see the following forum post. https://support.dataaccess.com/Forums/showthread.php?57177-VdfSplat-alfa-1-DataFlex-Debugger&amp;amp;p=299704#post299704&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDView1.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDView2.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDView3.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDView4.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDViewForeignTab.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDViewRelationshipsTab.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDViewViewTableTab.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-EvalObjects.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-EvalProperty.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-EvalPropertyOf.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-ObjectInspector.png]]&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
*This tool is currently (March 2020) in alpha stage.&lt;br /&gt;
&lt;br /&gt;
==Articles==&lt;br /&gt;
* [[Using dfSplat to identify object leaks]]&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
*[https://projects.vdf-guidance.com/projects/dfsplat dfSplat homepage]  &lt;br /&gt;
*[https://projects.vdf-guidance.com/projects/dfsplat/files dfSplat downloads]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Development Tools]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=DfSplat&amp;diff=3548</id>
		<title>DfSplat</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=DfSplat&amp;diff=3548"/>
		<updated>2023-03-07T10:31:19Z</updated>

		<summary type="html">&lt;p&gt;Wil: Removing some really obsolete images&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;dfSPlat&#039;&#039;&#039; is a free open source third party tool, intended to help with debugging DataFlex applications. It is written in DataFlex and wraps the DataFlex development components in order to run. At this moment it can be used to debug applications from Visual DataFlex 12.0 up to DataFlex 19.1&lt;br /&gt;
&lt;br /&gt;
==Random screenshots==&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDView1.png]]&lt;br /&gt;
[[File:dfSplat-DDView2.png]]&lt;br /&gt;
[[File:dfSplat-DDView3.png]]&lt;br /&gt;
[[File:dfSplat-DDView4.png]]&lt;br /&gt;
[[File:dfSplat-DDViewForeignTab.png]]&lt;br /&gt;
[[File:dfSplat-DDViewRelationshipsTab.png]]&lt;br /&gt;
[[File:dfSplat-DDViewViewTableTab.png]]&lt;br /&gt;
[[File:dfSplat-EvalObjects.png]]&lt;br /&gt;
[[File:dfSplat-EvalProperty.png]]&lt;br /&gt;
[[File:dfSplat-EvalPropertyOf.png]]&lt;br /&gt;
[[File:dfSplat-ObjectInspector.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
*This tool is currently (March 2020) in alpha stage.&lt;br /&gt;
&lt;br /&gt;
==Articles==&lt;br /&gt;
* [[Using dfSplat to identify object leaks]]&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
*[https://projects.vdf-guidance.com/projects/dfsplat dfSplat homepage]  &lt;br /&gt;
*[https://projects.vdf-guidance.com/projects/dfsplat/files dfSplat downloads]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Development Tools]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=File:DfSplat-ObjectInspectorDDO2.png&amp;diff=3547</id>
		<title>File:DfSplat-ObjectInspectorDDO2.png</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=File:DfSplat-ObjectInspectorDDO2.png&amp;diff=3547"/>
		<updated>2023-03-07T10:30:41Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=File:DfSplat-ObjectInspectorDDO.png&amp;diff=3546</id>
		<title>File:DfSplat-ObjectInspectorDDO.png</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=File:DfSplat-ObjectInspectorDDO.png&amp;diff=3546"/>
		<updated>2023-03-07T10:29:53Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=File:DfSplat-ObjectInspector.png&amp;diff=3545</id>
		<title>File:DfSplat-ObjectInspector.png</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=File:DfSplat-ObjectInspector.png&amp;diff=3545"/>
		<updated>2023-03-07T10:29:21Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=File:DfSplat-EvalPropertyOf.png&amp;diff=3544</id>
		<title>File:DfSplat-EvalPropertyOf.png</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=File:DfSplat-EvalPropertyOf.png&amp;diff=3544"/>
		<updated>2023-03-07T10:28:47Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=File:DfSplat-EvalProperty.png&amp;diff=3543</id>
		<title>File:DfSplat-EvalProperty.png</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=File:DfSplat-EvalProperty.png&amp;diff=3543"/>
		<updated>2023-03-07T10:28:19Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=File:DfSplat-EvalObjects.png&amp;diff=3542</id>
		<title>File:DfSplat-EvalObjects.png</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=File:DfSplat-EvalObjects.png&amp;diff=3542"/>
		<updated>2023-03-07T10:27:39Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=File:DfSplat-DDViewViewTableTab.png&amp;diff=3541</id>
		<title>File:DfSplat-DDViewViewTableTab.png</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=File:DfSplat-DDViewViewTableTab.png&amp;diff=3541"/>
		<updated>2023-03-07T10:27:12Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=File:DfSplat-DDViewRelationshipsTab.png&amp;diff=3540</id>
		<title>File:DfSplat-DDViewRelationshipsTab.png</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=File:DfSplat-DDViewRelationshipsTab.png&amp;diff=3540"/>
		<updated>2023-03-07T10:26:43Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=File:DfSplat-DDViewForeignTab.png&amp;diff=3539</id>
		<title>File:DfSplat-DDViewForeignTab.png</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=File:DfSplat-DDViewForeignTab.png&amp;diff=3539"/>
		<updated>2023-03-07T10:25:27Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=File:DfSplat-DDView4.png&amp;diff=3538</id>
		<title>File:DfSplat-DDView4.png</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=File:DfSplat-DDView4.png&amp;diff=3538"/>
		<updated>2023-03-07T10:24:54Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=File:DfSplat-DDView3.png&amp;diff=3537</id>
		<title>File:DfSplat-DDView3.png</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=File:DfSplat-DDView3.png&amp;diff=3537"/>
		<updated>2023-03-07T10:24:29Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=File:DfSplat-DDView2.png&amp;diff=3536</id>
		<title>File:DfSplat-DDView2.png</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=File:DfSplat-DDView2.png&amp;diff=3536"/>
		<updated>2023-03-07T10:24:07Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=File:DfSplat-DDView1.png&amp;diff=3535</id>
		<title>File:DfSplat-DDView1.png</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=File:DfSplat-DDView1.png&amp;diff=3535"/>
		<updated>2023-03-07T10:23:35Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=DfSplat&amp;diff=3534</id>
		<title>DfSplat</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=DfSplat&amp;diff=3534"/>
		<updated>2023-03-07T10:22:47Z</updated>

		<summary type="html">&lt;p&gt;Wil: Adding old screenshots&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;dfSPlat&#039;&#039;&#039; is a free open source third party tool, intended to help with debugging DataFlex applications. It is written in DataFlex and wraps the DataFlex development components in order to run. At this moment it can be used to debug applications from Visual DataFlex 12.0 up to DataFlex 19.1&lt;br /&gt;
&lt;br /&gt;
==Random screenshots==&lt;br /&gt;
&lt;br /&gt;
[[File:dfSplat-DDView1.png]]&lt;br /&gt;
[[File:dfSplat-DDView2.png]]&lt;br /&gt;
[[File:dfSplat-DDView3.png]]&lt;br /&gt;
[[File:dfSplat-DDView4.png]]&lt;br /&gt;
[[File:dfSplat-DDViewForeignTab.png]]&lt;br /&gt;
[[File:dfSplat-DDViewRelationshipsTab.png]]&lt;br /&gt;
[[File:dfSplat-DDViewViewTableTab.png]]&lt;br /&gt;
[[File:dfSplat-EvalObjects.png]]&lt;br /&gt;
[[File:dfSplat-EvalProperty.png]]&lt;br /&gt;
[[File:dfSplat-EvalPropertyOf.png]]&lt;br /&gt;
[[File:dfSplat-ObjectInspector.png]]&lt;br /&gt;
[[File:dfSplat-ObjectInspectorDDO.png]]&lt;br /&gt;
[[File:dfSplat-ObjectInspectorDDO2.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
*This tool is currently (March 2020) in alpha stage.&lt;br /&gt;
&lt;br /&gt;
==Articles==&lt;br /&gt;
* [[Using dfSplat to identify object leaks]]&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
*[https://projects.vdf-guidance.com/projects/dfsplat dfSplat homepage]  &lt;br /&gt;
*[https://projects.vdf-guidance.com/projects/dfsplat/files dfSplat downloads]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Development Tools]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Codejock&amp;diff=3533</id>
		<title>Codejock</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Codejock&amp;diff=3533"/>
		<updated>2022-12-20T11:19:23Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Code Jock is a suite of components that enhance the graphical interface to DataFlex.&lt;br /&gt;
It is included in the development environment since Visual DataFlex version 12.0.&lt;br /&gt;
&lt;br /&gt;
* [[Code Jock menus]]&lt;br /&gt;
* [[Dynamic codejock menus from a database]]&lt;br /&gt;
* [[How to add your own items to the default Codejock Context menu]]&lt;br /&gt;
* [[Add icons with subset of images to CodeJock CommandBars]]&lt;br /&gt;
* [[Codejock Grid with ProgressBar]]&lt;br /&gt;
* [[Time edit grid column for cCJGrid]]&lt;br /&gt;
* [[Apply color to codejock grid column headers]]&lt;br /&gt;
* [[cCJGrid custom row height]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Codejock]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Codejock&amp;diff=3532</id>
		<title>Codejock</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Codejock&amp;diff=3532"/>
		<updated>2022-12-20T11:17:22Z</updated>

		<summary type="html">&lt;p&gt;Wil: removal &amp;quot;stub&amp;quot; tag&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Code Jock adds a new visual interface to Visual DataFlex&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* [[Code Jock menus]]&lt;br /&gt;
* [[Dynamic codejock menus from a database]]&lt;br /&gt;
* [[How to add your own items to the default Codejock Context menu]]&lt;br /&gt;
* [[Add icons with subset of images to CodeJock CommandBars]]&lt;br /&gt;
* [[Codejock Grid with ProgressBar]]&lt;br /&gt;
* [[Time edit grid column for cCJGrid]]&lt;br /&gt;
* [[Apply color to codejock grid column headers]]&lt;br /&gt;
* [[cCJGrid custom row height]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Codejock]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Codejock&amp;diff=3531</id>
		<title>Codejock</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Codejock&amp;diff=3531"/>
		<updated>2022-12-20T11:16:50Z</updated>

		<summary type="html">&lt;p&gt;Wil: Adding a few other codejock articles here&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Code Jock adds a new visual interface to Visual DataFlex&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* [[Code Jock menus]]&lt;br /&gt;
* [[Dynamic codejock menus from a database]]&lt;br /&gt;
* [[How to add your own items to the default Codejock Context menu]]&lt;br /&gt;
* [[Add icons with subset of images to CodeJock CommandBars]]&lt;br /&gt;
* [[Codejock Grid with ProgressBar]]&lt;br /&gt;
* [[Time edit grid column for cCJGrid]]&lt;br /&gt;
* [[Apply color to codejock grid column headers]]&lt;br /&gt;
* [[cCJGrid custom row height]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Codejock]] [[Category:Stub]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=CCJGrid_custom_row_height&amp;diff=3530</id>
		<title>CCJGrid custom row height</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=CCJGrid_custom_row_height&amp;diff=3530"/>
		<updated>2022-12-20T11:12:07Z</updated>

		<summary type="html">&lt;p&gt;Wil: Cleanup code that isn&amp;#039;t used (less is more)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Normally you can&#039;t set the row height for an individual row in a codejock grid.&lt;br /&gt;
&lt;br /&gt;
The following code shows you how-to do that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
Use Windows.pkg&lt;br /&gt;
Use DFClient.pkg&lt;br /&gt;
&lt;br /&gt;
Use cCJGrid.pkg&lt;br /&gt;
Use cCJGridColumn.pkg&lt;br /&gt;
&lt;br /&gt;
Deferred_View Activate_oListWithImage for ;&lt;br /&gt;
Object oListWithImage is a dbView&lt;br /&gt;
  Set Border_Style to Border_Thick&lt;br /&gt;
  Set Size to 332 591&lt;br /&gt;
  Set Location to 2 2&lt;br /&gt;
  Set Label to &amp;quot;ListWithImage&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  Object oThisProductList is a cCJGrid&lt;br /&gt;
    Set Size to 325 580&lt;br /&gt;
    Set Location to 4 5&lt;br /&gt;
    &lt;br /&gt;
    Set pbReadOnly to True&lt;br /&gt;
    &lt;br /&gt;
    Procedure OnComMeasureRow Variant llRow OLE_HANDLE llhDC Integer llWidth Integer ByRef llHeight&lt;br /&gt;
      Move 75 to llHeight&lt;br /&gt;
      Forward Send OnComMeasureRow llRow llhDC llWidth llHeight          &lt;br /&gt;
    End_Procedure&lt;br /&gt;
    &lt;br /&gt;
    Procedure ResetGrid&lt;br /&gt;
      Handle  hoPaint&lt;br /&gt;
      Integer iCustomDraw&lt;br /&gt;
      Boolean bIsVirtual bUseFocusCell&lt;br /&gt;
      Boolean bFixed&lt;br /&gt;
      &lt;br /&gt;
      Get phoReportPaintManager to hoPaint&lt;br /&gt;
      Forward Send ResetGrid&lt;br /&gt;
      Get pbUseFocusCellRectangle to bUseFocusCell&lt;br /&gt;
      Move 0 to iCustomDraw&lt;br /&gt;
      If bUseFocusCell Begin&lt;br /&gt;
          Move (xtpCustomDrawItem) to iCustomDraw&lt;br /&gt;
      End&lt;br /&gt;
      Move (iCustomDraw ior xtpCustomBeforeDrawRow ior xtpCustomMeasureRow) to iCustomDraw&lt;br /&gt;
      &lt;br /&gt;
      Get ComFixedRowHeight of hoPaint to bFixed // ComSetCustomDraw resets this to True, must be restored&lt;br /&gt;
      Send ComSetCustomDraw iCustomDraw&lt;br /&gt;
      Set ComFixedRowHeight of hoPaint to bFixed&lt;br /&gt;
    End_Procedure&lt;br /&gt;
    &lt;br /&gt;
    Object oSTMAS_THUMBNAIL is a cCJGridColumn&lt;br /&gt;
      Set piWidth to 100&lt;br /&gt;
      Set pbEditable to False&lt;br /&gt;
      Set pbMultiLine to True&lt;br /&gt;
      &lt;br /&gt;
      Function DisplayImage String sImageName Returns String&lt;br /&gt;
        String  sXAML&lt;br /&gt;
        &lt;br /&gt;
        Move &amp;quot;&amp;quot; to sXAML&lt;br /&gt;
        Append sXAML &#039;&amp;lt;StackPanel  HorizontalAlignment=&amp;quot;Center&amp;quot; Name=&amp;quot;Grid1&amp;quot; VerticalAlignment=&amp;quot;Top&amp;quot;&amp;gt;&#039;&lt;br /&gt;
        Append sXAML   &#039;&amp;lt;Border HorizontalAlignment=&amp;quot;Center&amp;quot; Name=&amp;quot;Border1&amp;quot; VerticalAlignment=&amp;quot;Top&amp;quot; Background=&amp;quot;White&amp;quot; BorderBrush=&amp;quot;#FF1FA3EB&amp;quot; BorderThickness=&amp;quot;0,0,0,0&amp;quot;&amp;gt;&#039;&lt;br /&gt;
        Append sXAML     &#039;&amp;lt;Image Name=&amp;quot;Image1&amp;quot; Stretch=&amp;quot;Uniform&amp;quot; Width=&amp;quot;75px&amp;quot; Height=&amp;quot;75px&amp;quot; Source=&amp;quot;%1&amp;quot; /&amp;gt;&#039;&lt;br /&gt;
        Append sXAML   &#039;&amp;lt;/Border&amp;gt;&#039;&lt;br /&gt;
        Append sXAML &#039;&amp;lt;/StackPanel&amp;gt;&#039;&lt;br /&gt;
        &lt;br /&gt;
        Move (SFormat(sXAML, sImageName)) to sXAML&lt;br /&gt;
        Function_Return sXAML&lt;br /&gt;
      End_Function&lt;br /&gt;
      &lt;br /&gt;
      Procedure OnCreateColumn&lt;br /&gt;
        Forward Send OnCreateColumn&lt;br /&gt;
        Delegate Set ComEnableMarkup to True&lt;br /&gt;
      End_Procedure&lt;br /&gt;
    End_Object&lt;br /&gt;
&lt;br /&gt;
    Object oSTMAS_CODE is a cCJGridColumn&lt;br /&gt;
      Set piWidth to 197&lt;br /&gt;
      Set psCaption to &amp;quot;Product&amp;quot;&lt;br /&gt;
      Set pbEditable to False&lt;br /&gt;
    End_Object&lt;br /&gt;
    &lt;br /&gt;
    Procedure LoadData&lt;br /&gt;
      tDataSourceRow[] MyData&lt;br /&gt;
      String sXAML&lt;br /&gt;
      String sPath&lt;br /&gt;
      &lt;br /&gt;
      Send ResetGrid&lt;br /&gt;
      Get psBitmapPath of (phoWorkspace(ghoApplication)) to sPath&lt;br /&gt;
      Get DisplayImage of oSTMAS_THUMBNAIL (sPath+&amp;quot;\01.01.01_t.jpg&amp;quot;) to sXAML // Put the image in the bitmap path&lt;br /&gt;
      &lt;br /&gt;
      Move sXAML      to MyData[0].sValue[0]&lt;br /&gt;
      Move &amp;quot;01.01.01&amp;quot; to MyData[0].sValue[1]&lt;br /&gt;
      &lt;br /&gt;
      Send ReInitializeData MyData False&lt;br /&gt;
    End_Procedure&lt;br /&gt;
    &lt;br /&gt;
    Procedure Activating&lt;br /&gt;
      Forward Send Activating&lt;br /&gt;
      Send LoadData&lt;br /&gt;
    End_Procedure&lt;br /&gt;
  End_Object&lt;br /&gt;
&lt;br /&gt;
Cd_End_Object&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also: [https://support.dataaccess.com/Forums/showthread.php?67605-cCJGrid-Row-Height cCJGrid Row Height]&lt;br /&gt;
&lt;br /&gt;
[[Category:Codejock]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=CCJGrid_custom_row_height&amp;diff=3529</id>
		<title>CCJGrid custom row height</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=CCJGrid_custom_row_height&amp;diff=3529"/>
		<updated>2022-12-20T11:08:16Z</updated>

		<summary type="html">&lt;p&gt;Wil: Created page with &amp;quot;Normally you can&amp;#039;t set the row height for an individual row in a codejock grid.  The following code shows you how-to do that.  &amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt; Use Windows.pkg Use DFClient.pkg  Use cCJGrid.pkg Use cCJGridColumn.pkg  Deferred_View Activate_oListWithImage for ; Object oListWithImage is a dbView   Set Border_Style to Border_Thick   Set Size to 332 591   Set Location to 2 2   Set Label to &amp;quot;ListWithImage&amp;quot;      Object oThisProductList is a cCJGrid     Set Size to 325...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Normally you can&#039;t set the row height for an individual row in a codejock grid.&lt;br /&gt;
&lt;br /&gt;
The following code shows you how-to do that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
Use Windows.pkg&lt;br /&gt;
Use DFClient.pkg&lt;br /&gt;
&lt;br /&gt;
Use cCJGrid.pkg&lt;br /&gt;
Use cCJGridColumn.pkg&lt;br /&gt;
&lt;br /&gt;
Deferred_View Activate_oListWithImage for ;&lt;br /&gt;
Object oListWithImage is a dbView&lt;br /&gt;
  Set Border_Style to Border_Thick&lt;br /&gt;
  Set Size to 332 591&lt;br /&gt;
  Set Location to 2 2&lt;br /&gt;
  Set Label to &amp;quot;ListWithImage&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  Object oThisProductList is a cCJGrid&lt;br /&gt;
    Set Size to 325 580&lt;br /&gt;
    Set Location to 4 5&lt;br /&gt;
    &lt;br /&gt;
    Set pbReadOnly to True&lt;br /&gt;
    &lt;br /&gt;
    Procedure OnComMeasureRow Variant llRow OLE_HANDLE llhDC Integer llWidth Integer ByRef llHeight&lt;br /&gt;
      Move 75 to llHeight&lt;br /&gt;
      Forward Send OnComMeasureRow llRow llhDC llWidth llHeight          &lt;br /&gt;
    End_Procedure&lt;br /&gt;
    &lt;br /&gt;
    Procedure ResetGrid&lt;br /&gt;
      Handle  hoPaint&lt;br /&gt;
      Integer iCustomDraw&lt;br /&gt;
      Boolean bIsVirtual bUseFocusCell&lt;br /&gt;
      Boolean bFixed&lt;br /&gt;
      &lt;br /&gt;
      Get phoReportPaintManager to hoPaint&lt;br /&gt;
      Forward Send ResetGrid&lt;br /&gt;
      Get pbUseFocusCellRectangle to bUseFocusCell&lt;br /&gt;
      Move 0 to iCustomDraw&lt;br /&gt;
      If bUseFocusCell Begin&lt;br /&gt;
          Move (xtpCustomDrawItem) to iCustomDraw&lt;br /&gt;
      End&lt;br /&gt;
      Move (iCustomDraw ior xtpCustomBeforeDrawRow ior xtpCustomMeasureRow) to iCustomDraw&lt;br /&gt;
      &lt;br /&gt;
      Get ComFixedRowHeight of hoPaint to bFixed // ComSetCustomDraw resets this to True, must be restored&lt;br /&gt;
      Send ComSetCustomDraw iCustomDraw&lt;br /&gt;
      Set ComFixedRowHeight of hoPaint to bFixed&lt;br /&gt;
    End_Procedure&lt;br /&gt;
    &lt;br /&gt;
    Object oSTMAS_THUMBNAIL is a cCJGridColumn&lt;br /&gt;
      Set piWidth to 100&lt;br /&gt;
      Set pbEditable to False&lt;br /&gt;
      Set pbMultiLine to True&lt;br /&gt;
      &lt;br /&gt;
      Function DisplayImage String sImageName Returns String&lt;br /&gt;
        String  sXAML&lt;br /&gt;
        &lt;br /&gt;
        Send OnSetImageName (&amp;amp;sImageName)&lt;br /&gt;
        &lt;br /&gt;
        Move &amp;quot;&amp;quot; to sXAML&lt;br /&gt;
        Append sXAML &#039;&amp;lt;StackPanel  HorizontalAlignment=&amp;quot;Center&amp;quot; Name=&amp;quot;Grid1&amp;quot; VerticalAlignment=&amp;quot;Top&amp;quot;&amp;gt;&#039;&lt;br /&gt;
        Append sXAML   &#039;&amp;lt;Border HorizontalAlignment=&amp;quot;Center&amp;quot; Name=&amp;quot;Border1&amp;quot; VerticalAlignment=&amp;quot;Top&amp;quot; Background=&amp;quot;White&amp;quot; BorderBrush=&amp;quot;#FF1FA3EB&amp;quot; BorderThickness=&amp;quot;0,0,0,0&amp;quot;&amp;gt;&#039;&lt;br /&gt;
        Append sXAML     &#039;&amp;lt;Image Name=&amp;quot;Image1&amp;quot; Stretch=&amp;quot;Uniform&amp;quot; Width=&amp;quot;75px&amp;quot; Height=&amp;quot;75px&amp;quot; Source=&amp;quot;%1&amp;quot; /&amp;gt;&#039;&lt;br /&gt;
        Append sXAML   &#039;&amp;lt;/Border&amp;gt;&#039;&lt;br /&gt;
        Append sXAML &#039;&amp;lt;/StackPanel&amp;gt;&#039;&lt;br /&gt;
        &lt;br /&gt;
        Move (SFormat(sXAML, sImageName)) to sXAML&lt;br /&gt;
        Function_Return sXAML&lt;br /&gt;
      End_Function&lt;br /&gt;
      &lt;br /&gt;
      Procedure OnCreateColumn&lt;br /&gt;
        Forward Send OnCreateColumn&lt;br /&gt;
        Delegate Set ComEnableMarkup to True&lt;br /&gt;
      End_Procedure&lt;br /&gt;
      &lt;br /&gt;
      Procedure OnSetImageName String ByRef sImageName&lt;br /&gt;
      End_Procedure&lt;br /&gt;
      &lt;br /&gt;
      Procedure OnSetCalculatedValue String ByRef sValue&lt;br /&gt;
        Forward Send OnSetCalculatedValue (&amp;amp;sValue)&lt;br /&gt;
      End_Procedure&lt;br /&gt;
      &lt;br /&gt;
      Procedure OnSetDisplayMetrics Handle hoGridItemMetrics Integer iRow String ByRef sValue&lt;br /&gt;
        Forward Send OnSetDisplayMetrics hoGridItemMetrics iRow (&amp;amp;sValue)&lt;br /&gt;
      End_Procedure&lt;br /&gt;
    End_Object&lt;br /&gt;
&lt;br /&gt;
    Object oSTMAS_CODE is a cCJGridColumn&lt;br /&gt;
      Set piWidth to 197&lt;br /&gt;
      Set psCaption to &amp;quot;Product&amp;quot;&lt;br /&gt;
      Set pbEditable to False&lt;br /&gt;
    End_Object&lt;br /&gt;
    &lt;br /&gt;
    Procedure LoadData&lt;br /&gt;
      tDataSourceRow[] MyData&lt;br /&gt;
      String sXAML&lt;br /&gt;
      String sPath&lt;br /&gt;
      &lt;br /&gt;
      Send ResetGrid&lt;br /&gt;
      Get psBitmapPath of (phoWorkspace(ghoApplication)) to sPath&lt;br /&gt;
      Get DisplayImage of oSTMAS_THUMBNAIL (sPath+&amp;quot;\01.01.01_t.jpg&amp;quot;) to sXAML // Put the image in the bitmap path&lt;br /&gt;
      &lt;br /&gt;
      Move sXAML      to MyData[0].sValue[0]&lt;br /&gt;
      Move &amp;quot;01.01.01&amp;quot; to MyData[0].sValue[1]&lt;br /&gt;
      &lt;br /&gt;
      Send ReInitializeData MyData False&lt;br /&gt;
    End_Procedure&lt;br /&gt;
    &lt;br /&gt;
    Procedure Activating&lt;br /&gt;
      Forward Send Activating&lt;br /&gt;
      Send LoadData&lt;br /&gt;
    End_Procedure&lt;br /&gt;
  End_Object&lt;br /&gt;
&lt;br /&gt;
Cd_End_Object&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also: [https://support.dataaccess.com/Forums/showthread.php?67605-cCJGrid-Row-Height cCJGrid Row Height]&lt;br /&gt;
&lt;br /&gt;
[[Category:Codejock]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Codejock&amp;diff=3528</id>
		<title>Codejock</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Codejock&amp;diff=3528"/>
		<updated>2022-12-20T11:03:16Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Code Jock adds a new visual interface to Visual DataFlex&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* [[Code Jock menus]]&lt;br /&gt;
* [[Apply color to codejock grid column headers]]&lt;br /&gt;
* [[cCJGrid custom row height]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Codejock]] [[Category:Stub]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Apply_color_to_codejock_grid_column_headers&amp;diff=3527</id>
		<title>Apply color to codejock grid column headers</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Apply_color_to_codejock_grid_column_headers&amp;diff=3527"/>
		<updated>2022-12-19T17:45:51Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Sometimes you might want to color your grid column header.&lt;br /&gt;
This is not natively supported via the DataFlex wrapper for the codejock grids.&lt;br /&gt;
&lt;br /&gt;
You can however get this by using the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
    // In the cCjDbGrid&lt;br /&gt;
    Procedure OnCreate&lt;br /&gt;
        Handle hoMarkUpContext&lt;br /&gt;
        Variant vMarkUpContext&lt;br /&gt;
        String  sMarkup&lt;br /&gt;
        Handle hoReportColumns&lt;br /&gt;
        Handle hoReportColumn&lt;br /&gt;
        Integer iCols&lt;br /&gt;
        Integer iDisplayIndex&lt;br /&gt;
        Integer iMyColumn&lt;br /&gt;
        Variant vCol&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        Forward Send OnCreate&lt;br /&gt;
        &lt;br /&gt;
        // As we use markup, we have to enable it and do so early on&lt;br /&gt;
        Set ComEnableMarkup to True&lt;br /&gt;
        &lt;br /&gt;
        // Color one column header yellow&lt;br /&gt;
        Get phoReportColumns to hoReportColumns&lt;br /&gt;
        Get phoReportColumn to hoReportColumn&lt;br /&gt;
        Get ComCount of hoReportColumns to iCols&lt;br /&gt;
        Move 1 to iMyColumn&lt;br /&gt;
        For iDisplayIndex from 0 to (iCols-1)&lt;br /&gt;
            Get ComColumn of hoReportColumns iDisplayIndex to vCol&lt;br /&gt;
            If (iDisplayIndex=iMyColumn) Begin&lt;br /&gt;
              Set pvComObject of hoReportColumn to vCol&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
              Move &amp;quot;&amp;lt;Border xmlns=&#039;http://schemas.microsoft.com/winfx/2006/xaml/presentation&#039; xmlns:x=&#039;http://schemas.microsoft.com/winfx/2006/xaml&#039;&amp;gt;&amp;quot; to sMarkup&lt;br /&gt;
              Append sMarkup &amp;quot;    &amp;lt;Border.Background&amp;gt;    &amp;quot;&lt;br /&gt;
              Append sMarkup &#039;        &amp;lt;LinearGradientBrush StartPoint=&amp;quot;0, 0&amp;quot; EndPoint=&amp;quot;1,0&amp;quot;&amp;gt;&#039;&lt;br /&gt;
              Append sMarkup &#039;            &amp;lt;GradientStop Color=&amp;quot;Yellow&amp;quot; Offset=&amp;quot;0&amp;quot;/&amp;gt;&#039;&lt;br /&gt;
              Append sMarkup &amp;quot;        &amp;lt;/LinearGradientBrush&amp;gt;        &amp;quot;&lt;br /&gt;
              Append sMarkup &amp;quot;    &amp;lt;/Border.Background&amp;gt;&amp;quot;&lt;br /&gt;
              Append sMarkup &#039;    &amp;lt;TextBlock Name=&amp;quot;Sent&amp;quot; HorizontalAlignment=&amp;quot;Left&amp;quot; Cursor=&amp;quot;Hand&amp;quot;&amp;gt;Sent items&amp;lt;/TextBlock&amp;gt;&#039;&lt;br /&gt;
              Append sMarkup &amp;quot;&amp;lt;/Border&amp;gt;&amp;quot;&lt;br /&gt;
              Set ComCaption of hoReportColumn to sMarkup&lt;br /&gt;
            End&lt;br /&gt;
        Loop&lt;br /&gt;
    End_Procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See also: [https://support.dataaccess.com/Forums/showthread.php?69298-Colour-(or-Color)-in-cDbCjGrids&amp;amp;p=377675#post377675 Colour (or Color) in cDbCjGrids (DataFlex forums)] &lt;br /&gt;
&lt;br /&gt;
[[Category:Codejock]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Apply_color_to_codejock_grid_column_headers&amp;diff=3526</id>
		<title>Apply color to codejock grid column headers</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Apply_color_to_codejock_grid_column_headers&amp;diff=3526"/>
		<updated>2022-12-19T17:44:05Z</updated>

		<summary type="html">&lt;p&gt;Wil: Created page with &amp;quot;Sometimes you might want to color your grid column header. This is not natively supported via the DataFlex wrapper for the codejock grids.  You can however get this by using the following code:  &amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;     // In the cCjDbGrid     Procedure OnCreate         Handle hoMarkUpContext         Variant vMarkUpContext         String  sMarkup         Handle hoReportColumns         Handle hoReportColumn         Integer iCols         Integer iDisplayIndex         I...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Sometimes you might want to color your grid column header.&lt;br /&gt;
This is not natively supported via the DataFlex wrapper for the codejock grids.&lt;br /&gt;
&lt;br /&gt;
You can however get this by using the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
    // In the cCjDbGrid&lt;br /&gt;
    Procedure OnCreate&lt;br /&gt;
        Handle hoMarkUpContext&lt;br /&gt;
        Variant vMarkUpContext&lt;br /&gt;
        String  sMarkup&lt;br /&gt;
        Handle hoReportColumns&lt;br /&gt;
        Handle hoReportColumn&lt;br /&gt;
        Integer iCols&lt;br /&gt;
        Integer iDisplayIndex&lt;br /&gt;
        Integer iMyColumn&lt;br /&gt;
        Variant vCol&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        Forward Send OnCreate&lt;br /&gt;
        &lt;br /&gt;
        // As we use markup, we have to enable it and do so early on&lt;br /&gt;
        Set ComEnableMarkup to True&lt;br /&gt;
        &lt;br /&gt;
        // Color one column header yellow&lt;br /&gt;
        Get phoReportColumns to hoReportColumns&lt;br /&gt;
        Get phoReportColumn to hoReportColumn&lt;br /&gt;
        Get ComCount of hoReportColumns to iCols&lt;br /&gt;
        Move 1 to iMyColumn&lt;br /&gt;
        For iDisplayIndex from 0 to (iCols-1)&lt;br /&gt;
            Get ComColumn of hoReportColumns iDisplayIndex to vCol&lt;br /&gt;
            If (iDisplayIndex=iMyColumn) Begin&lt;br /&gt;
              Set pvComObject of hoReportColumn to vCol&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
              Move &amp;quot;&amp;lt;Border xmlns=&#039;http://schemas.microsoft.com/winfx/2006/xaml/presentation&#039; xmlns:x=&#039;http://schemas.microsoft.com/winfx/2006/xaml&#039;&amp;gt;&amp;quot; to sMarkup&lt;br /&gt;
              Append sMarkup &amp;quot;    &amp;lt;Border.Background&amp;gt;    &amp;quot;&lt;br /&gt;
              Append sMarkup &#039;        &amp;lt;LinearGradientBrush StartPoint=&amp;quot;0, 0&amp;quot; EndPoint=&amp;quot;1,0&amp;quot;&amp;gt;&#039;&lt;br /&gt;
              Append sMarkup &#039;            &amp;lt;GradientStop Color=&amp;quot;Yellow&amp;quot; Offset=&amp;quot;0&amp;quot;/&amp;gt;&#039;&lt;br /&gt;
              Append sMarkup &amp;quot;        &amp;lt;/LinearGradientBrush&amp;gt;        &amp;quot;&lt;br /&gt;
              Append sMarkup &amp;quot;    &amp;lt;/Border.Background&amp;gt;&amp;quot;&lt;br /&gt;
              Append sMarkup &#039;    &amp;lt;TextBlock Name=&amp;quot;Sent&amp;quot; HorizontalAlignment=&amp;quot;Left&amp;quot; Cursor=&amp;quot;Hand&amp;quot;&amp;gt;Sent items&amp;lt;/TextBlock&amp;gt;&#039;&lt;br /&gt;
              Append sMarkup &amp;quot;&amp;lt;/Border&amp;gt;&amp;quot;&lt;br /&gt;
              Set ComCaption of hoReportColumn to sMarkup&lt;br /&gt;
            End&lt;br /&gt;
        Loop&lt;br /&gt;
    End_Procedure&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See also: https://support.dataaccess.com/Forums/showthread.php?69298-Colour-(or-Color)-in-cDbCjGrids&amp;amp;p=377675#post377675&lt;br /&gt;
&lt;br /&gt;
[[Category:Codejock]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Codejock&amp;diff=3525</id>
		<title>Codejock</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Codejock&amp;diff=3525"/>
		<updated>2022-12-19T17:40:15Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Code Jock adds a new visual interface to Visual DataFlex&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* [[Code Jock menus]]&lt;br /&gt;
* [[Apply color to codejock grid column headers]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Codejock]] [[Category:Stub]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Codejock&amp;diff=3524</id>
		<title>Codejock</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Codejock&amp;diff=3524"/>
		<updated>2022-12-19T17:39:41Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Code Jock adds a new visual interface to Visual DataFlex&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Code Jock menus]]&lt;br /&gt;
[[Color codejock grid column headers]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Codejock]] [[Category:Stub]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Get_the_selected_printer_device_name&amp;diff=3523</id>
		<title>Get the selected printer device name</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Get_the_selected_printer_device_name&amp;diff=3523"/>
		<updated>2022-09-15T10:34:50Z</updated>

		<summary type="html">&lt;p&gt;Wil: Created page with &amp;quot;DataFlex Reports has a class cPrintDialog which you can use to popup a printer dialog and then retrieve the selected printer from.  &amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;     Object oPrintDialog is a cPrintDialog     End_Object      Object oPrint is a Button         Set Location to 0 0         Set Label to &amp;quot;Print&amp;quot;              Procedure OnClick             Integer iRes             String  sPrntr                          Get PrintDialog of oPrintDialog to iRes...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;DataFlex Reports has a class cPrintDialog which you can use to popup a printer dialog and then retrieve the selected printer from.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dataflex&amp;quot;&amp;gt;&lt;br /&gt;
    Object oPrintDialog is a cPrintDialog&lt;br /&gt;
    End_Object&lt;br /&gt;
&lt;br /&gt;
    Object oPrint is a Button&lt;br /&gt;
        Set Location to 0 0&lt;br /&gt;
        Set Label to &amp;quot;Print&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
        Procedure OnClick&lt;br /&gt;
            Integer iRes&lt;br /&gt;
            String  sPrntr&lt;br /&gt;
            &lt;br /&gt;
            Get PrintDialog of oPrintDialog to iRes&lt;br /&gt;
            &lt;br /&gt;
            If iRes Begin&lt;br /&gt;
                Get psDeviceName of oPrintDialog to sPrntr&lt;br /&gt;
                &lt;br /&gt;
                Direct_Output (&amp;quot;WinLST:&amp;quot; * sPrntr)&lt;br /&gt;
                Writeln &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
                Close_Output&lt;br /&gt;
            End&lt;br /&gt;
            &lt;br /&gt;
        End_Procedure&lt;br /&gt;
    &lt;br /&gt;
    End_Object&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== External links ===&lt;br /&gt;
&lt;br /&gt;
* [https://support.dataaccess.com/Forums/showthread.php?68984-How-to-allow-the-user-to-select-a-printer How to allow the user to select a printer?]&lt;br /&gt;
&lt;br /&gt;
[[Category: Tutorials]]&lt;br /&gt;
[[Category: Windows Applications]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Portal:Windows_Applications&amp;diff=3522</id>
		<title>Portal:Windows Applications</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Portal:Windows_Applications&amp;diff=3522"/>
		<updated>2022-09-15T10:28:07Z</updated>

		<summary type="html">&lt;p&gt;Wil: /* Tutorials */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;&#039;Windows Applications Portal&#039;&#039;&#039; is the place to come for articles and tutorials on developing [http://en.wikipedia.org/wiki/Microsoft_Windows Windows] applications with &#039;&#039;&#039;[[DataFlex]]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Note: [[DataFlex]] was renamed from [[Visual DataFlex]], by Data Access Worldwide in 2014.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Articles==&lt;br /&gt;
*&#039;&#039;&#039;[[Visual DataFlex]]&#039;&#039;&#039; (covering the basic stuff)&lt;br /&gt;
&lt;br /&gt;
==Tutorials==&lt;br /&gt;
*How to [https://support.dataaccess.com/Forums/showthread.php?64430-HOWTO-Fix-RemoteApp-losing-focus-and-or-crashing-due-to-z-index-issue-on-Win10-Pro How to fix remote app losing focus and/or crashing due to z-index issue on Win10-Pro]&lt;br /&gt;
*How to add &#039;&#039;&#039;[[Add Workspace Parameter|Workspace Parameters]]&#039;&#039;&#039; using the [[cIniFile]] class&lt;br /&gt;
*[[Running_VDF_programs_as_Windows_Services]]&lt;br /&gt;
*[[Using On_key for undefined keys]]&lt;br /&gt;
*[[Passing the workspace as a parameter]]&lt;br /&gt;
*Adding [[SMTP Email]] to your application using an [[ActiveX]] control&lt;br /&gt;
*[[Run only one instance of your application]]&lt;br /&gt;
*[[Customize prompt lookup behavior in a dbgrid]]&lt;br /&gt;
*[[Print the content of an embedded IE html control]]&lt;br /&gt;
*[[Get the selected printer device name]]&lt;br /&gt;
*[[Return data from every object in a dbView]]&lt;br /&gt;
*[[Print to a file using reports]]&lt;br /&gt;
*[[Visual Modelling of multiple visual objects]]&lt;br /&gt;
*[[Using SQL Connectivity|SQL Connectivity]]&lt;br /&gt;
*[[Upgrading workspaces to a newer Visual DataFlex version]]&lt;br /&gt;
*[[Dynamic codejock menus from a database]]&lt;br /&gt;
*[[How to add your own items to the default Codejock Context menu]]&lt;br /&gt;
*[[Simulate submitting data from a web browser]]&lt;br /&gt;
*[[Using GIT for Dataflex Development]]&lt;br /&gt;
&lt;br /&gt;
==Advanced==&lt;br /&gt;
* [[Add icons with subset of images to CodeJock CommandBars]]&lt;br /&gt;
* [[Programmatically edit a treeview label]]&lt;br /&gt;
* [[Multi-row select for Grid control]]&lt;br /&gt;
* [[Calculating the cost of inventory kits]] - Functions that call themselves&lt;br /&gt;
* [[External dependencies]]&lt;br /&gt;
* [[Enumerate windows fonts]]&lt;br /&gt;
* [[Get Datadictionary object from File Number]]&lt;br /&gt;
* [[Codejock Grid with ProgressBar]]&lt;br /&gt;
* [[Time edit grid column for cCJGrid]]&lt;br /&gt;
&lt;br /&gt;
==External Resources==&lt;br /&gt;
* http://www.vdf-guidance.com&lt;br /&gt;
* http://www.dataaccess.com&lt;br /&gt;
* http://www.dataaccess.nl&lt;br /&gt;
* [http://www.sture.com/wasp/ WASP Newsgroup search] engine&lt;br /&gt;
* [http://www.starzen.com StarZen Technologies] Addon Tools, Books, Magazines, Consulting&lt;br /&gt;
* [http://www.moose-software.com Visual Dataflex for the Spanish speaking community] HelpDesk Software, Web App and Ajax applications, Electos&lt;br /&gt;
* [https://www.rdctools.com/ RDC Tools International] Open Source, Consulting &amp;amp; Tools&lt;br /&gt;
* http://eriksven.com/&lt;br /&gt;
* [https://discord.gg/abyersd DataFlex discord server]&lt;br /&gt;
&lt;br /&gt;
==Requested Articles / Works in progress==&lt;br /&gt;
&lt;br /&gt;
new articles go here! --[[User:Jka|Jka]] 22:49, 22 December 2008 (UTC)&lt;br /&gt;
&lt;br /&gt;
*[[Converting from DOS to Windows]]&lt;br /&gt;
*[[COM|Using COM Objects]] (reuse existing functionality)&lt;br /&gt;
*[[Scanning / TWAIN components]]&lt;br /&gt;
&lt;br /&gt;
*[[Some Link]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Portals]]&lt;br /&gt;
[[Category:DataFlex]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Handler_%22DataFlex_20.1_Web_Services_64bit%22_has_a_bad_module_%22IsapiModule%22_in_its_module_list&amp;diff=3521</id>
		<title>Handler &quot;DataFlex 20.1 Web Services 64bit&quot; has a bad module &quot;IsapiModule&quot; in its module list</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Handler_%22DataFlex_20.1_Web_Services_64bit%22_has_a_bad_module_%22IsapiModule%22_in_its_module_list&amp;diff=3521"/>
		<updated>2022-08-10T08:03:51Z</updated>

		<summary type="html">&lt;p&gt;Wil: Updated with Harm&amp;#039;s findings from the forum&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you use DataFlex 20.x to create webservices and not webapps that have a fancy new interface using the WebApp framework then you might bump into the following problem.&lt;br /&gt;
&lt;br /&gt;
* WebApps such as &amp;quot;WebOrderMobile&amp;quot; work fine&lt;br /&gt;
* Your WebServices using only the cWebAppBasic framework do not work.&lt;br /&gt;
&lt;br /&gt;
You&#039;re getting the following error when you try to browse to a .wso file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Bad-module-ISAPI-module.png|784px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;quot;HTTP Error 500.21 - Internal Server Error&lt;br /&gt;
Handler &amp;quot;DataFlex 20.1 Web Services 64bit&amp;quot; has a bad module &amp;quot;IsapiModule&amp;quot; in its module list&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This error actually gives a hint, but as the normal modules in IIS look fine and the same as in normal webapps you might be puzzled like I was.&lt;br /&gt;
&lt;br /&gt;
It wasn&#039;t until I ran DataFlex WebApp Check that it dawned upon me what was wrong.&lt;br /&gt;
&lt;br /&gt;
The cBasicWebApp class depends on IIS ASP Classic which installs ISAPI modules!&lt;br /&gt;
&lt;br /&gt;
Normally the DataFlex 20.1 installer takes care of that, but in case it did not, or if IIS was pre configured and you bump in the above error. Then now you know what to do.&lt;br /&gt;
&lt;br /&gt;
So follow the steps from the DataFlex WebApp Check application to install that and your problems are solved.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Web Applications]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Handler_%22DataFlex_20.1_Web_Services_64bit%22_has_a_bad_module_%22IsapiModule%22_in_its_module_list&amp;diff=3520</id>
		<title>Handler &quot;DataFlex 20.1 Web Services 64bit&quot; has a bad module &quot;IsapiModule&quot; in its module list</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Handler_%22DataFlex_20.1_Web_Services_64bit%22_has_a_bad_module_%22IsapiModule%22_in_its_module_list&amp;diff=3520"/>
		<updated>2022-07-21T13:53:54Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you use DataFlex 20.x to create webservices and not webapps that have a fancy new interface using the WebApp framework then you might bump into the following problem.&lt;br /&gt;
&lt;br /&gt;
* WebApps such as &amp;quot;WebOrderMobile&amp;quot; work fine&lt;br /&gt;
* Your WebServices using only the cWebAppBasic framework do not work.&lt;br /&gt;
&lt;br /&gt;
You&#039;re getting the following error when you try to browse to a .wso file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Bad-module-ISAPI-module.png|784px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;quot;HTTP Error 500.21 - Internal Server Error&lt;br /&gt;
Handler &amp;quot;DataFlex 20.1 Web Services 64bit&amp;quot; has a bad module &amp;quot;IsapiModule&amp;quot; in its module list&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This error actually gives a hint, but as the normal modules in IIS look fine and the same as in normal webapps you might be puzzled like I was.&lt;br /&gt;
&lt;br /&gt;
It wasn&#039;t until I ran DataFlex WebApp Check that it dawned upon me what was wrong.&lt;br /&gt;
&lt;br /&gt;
The cBasicWebApp class depends on IIS ASP Classic!&lt;br /&gt;
&lt;br /&gt;
Note that while DataFlex 20.1 installs and configures IIS on your behalf, it _does_not_ configure ASP/IIS classic.&lt;br /&gt;
&lt;br /&gt;
So follow the steps from the DataFlex WebApp Check application to install that and your problems are solved.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Web Applications]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Handler_%22DataFlex_20.1_Web_Services_64bit%22_has_a_bad_module_%22IsapiModule%22_in_its_module_list&amp;diff=3519</id>
		<title>Handler &quot;DataFlex 20.1 Web Services 64bit&quot; has a bad module &quot;IsapiModule&quot; in its module list</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Handler_%22DataFlex_20.1_Web_Services_64bit%22_has_a_bad_module_%22IsapiModule%22_in_its_module_list&amp;diff=3519"/>
		<updated>2022-07-21T13:50:10Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you use DataFlex 20.x to create webservices and not webapps that have a fancy new interface using the WebApp framework then you might bump into the following problem.&lt;br /&gt;
&lt;br /&gt;
* WebApps such as &amp;quot;WebOrderMobile&amp;quot; work fine&lt;br /&gt;
* Your WebServices using only the cWebAppBasic framework do not work.&lt;br /&gt;
&lt;br /&gt;
You&#039;re getting the following error when you try to browse to a .wso file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Bad-module-ISAPI-module.png|784px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;quot;HTTP Error 500.21 - Internal Server Error&lt;br /&gt;
Handler &amp;quot;DataFlex 20.1 Web Services 64bit&amp;quot; has a bad module &amp;quot;IsapiModule&amp;quot; in its module list&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This error actually gives a hint, but as the normal modules in IIS look fine and the same as in normal webapps you might be puzzled like I was.&lt;br /&gt;
&lt;br /&gt;
It wasn&#039;t until I ran DataFlex WebApp Check that it dawned upon me what was wrong.&lt;br /&gt;
&lt;br /&gt;
The cBasicWebApp class depends on IIS ASP Classic!&lt;br /&gt;
&lt;br /&gt;
So follow the steps from the DataFlex WebApp Check application to install that and your problems are solved.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Web Applications]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Handler_%22DataFlex_20.1_Web_Services_64bit%22_has_a_bad_module_%22IsapiModule%22_in_its_module_list&amp;diff=3518</id>
		<title>Handler &quot;DataFlex 20.1 Web Services 64bit&quot; has a bad module &quot;IsapiModule&quot; in its module list</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Handler_%22DataFlex_20.1_Web_Services_64bit%22_has_a_bad_module_%22IsapiModule%22_in_its_module_list&amp;diff=3518"/>
		<updated>2022-07-21T13:48:37Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you use DataFlex 20.x to create webservices and not webapps that have a fancy new interface using the WebApp framework then you might bump into the following problem.&lt;br /&gt;
&lt;br /&gt;
* WebApps such as &amp;quot;WebOrderMobile&amp;quot; work fine&lt;br /&gt;
* Your WebServices using only the cWebAppBasic framework do not work.&lt;br /&gt;
&lt;br /&gt;
You&#039;re getting the following error when you try to browse to a .wso file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Bad-module-ISAPI-module.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;quot;HTTP Error 500.21 - Internal Server Error&lt;br /&gt;
Handler &amp;quot;DataFlex 20.1 Web Services 64bit&amp;quot; has a bad module &amp;quot;IsapiModule&amp;quot; in its module list&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This error actually gives a hint, but as the normal modules in IIS look fine and the same as in normal webapps you might be puzzled like I was.&lt;br /&gt;
&lt;br /&gt;
It wasn&#039;t until I ran DataFlex WebApp Check that it dawned upon me what was wrong.&lt;br /&gt;
&lt;br /&gt;
The cBasicWebApp class depends on IIS ASP Classic!&lt;br /&gt;
&lt;br /&gt;
So follow the steps from the DataFlex WebApp Check application to install that and your problems are solved.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Web Applications]]&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Handler_%22DataFlex_20.1_Web_Services_64bit%22_has_a_bad_module_%22IsapiModule%22_in_its_module_list&amp;diff=3517</id>
		<title>Handler &quot;DataFlex 20.1 Web Services 64bit&quot; has a bad module &quot;IsapiModule&quot; in its module list</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Handler_%22DataFlex_20.1_Web_Services_64bit%22_has_a_bad_module_%22IsapiModule%22_in_its_module_list&amp;diff=3517"/>
		<updated>2022-07-21T13:45:08Z</updated>

		<summary type="html">&lt;p&gt;Wil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you use DataFlex 20.x to create webservices and not webapps that have a fancy new interface using the WebApp framework then you might bump into the following problem.&lt;br /&gt;
&lt;br /&gt;
- WebApps such as &amp;quot;WebOrderMobile&amp;quot; work fine&lt;br /&gt;
- Your WebServices using only the cWebAppBasic framework do not work.&lt;br /&gt;
&lt;br /&gt;
You&#039;re getting the following error when you try to browse to a .wso file.&lt;br /&gt;
&lt;br /&gt;
[[File:Bad-module-ISAPI-module.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;quot;HTTP Error 500.21 - Internal Server Error&lt;br /&gt;
Handler &amp;quot;DataFlex 20.1 Web Services 64bit&amp;quot; has a bad module &amp;quot;IsapiModule&amp;quot; in its module list&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This error actually gives a hint, but as the normal modules in IIS look fine and the same as in normal webapps you might be puzzled like I was.&lt;br /&gt;
&lt;br /&gt;
It wasn&#039;t until I ran DataFlex WebApp Check that it dawned upon me what was wrong.&lt;br /&gt;
&lt;br /&gt;
The cBasicWebApp class depends on IIS ASP Classic!&lt;br /&gt;
&lt;br /&gt;
So follow the steps from the DataFlex WebApp Check application to install that and your problems are solved.&lt;/div&gt;</summary>
		<author><name>Wil</name></author>
	</entry>
</feed>