Had a quick play with this last night. I have a customer DBF with account, name and creditlim fields. So this program will list the table out, and then update one of the records. As you can see it is very recognisable to a VFP person, even though you would be able to do several things more concisely in VFP.
using system using system.collections.generic using system.linq using system.text
function start() as void strict
// -- This opens customers.dbf in the next empty work area, and specifies the CDX file to use. use "customers.dbf" new shared index "customers" select customers
// -- Sets the controlling index tag. set order to "account"
// -- List out the table. scan ? account, name, creditlim endscan
// -- Locate a record using the order set above. seek "ADA0001" if found()
// -- It doesn't seem to allow updating a record without an rlock() if rlock() replace creditlim with 1000 unlock endif
endif
? "Account ADA0001 credit limit now: " + str(creditlim)
wait
return
Hi Alan,
Well done and thanks for the testing work you doing.
Hmm not sure about VFP recognizable, it looks quite X# to me... :-P
Will just bash your code a little bit:
On 2019/10/23 11:08, Alan Bourke wrote:
// -- This opens customers.dbf in the next empty work area, and specifies the CDX file to use. use "customers.dbf" new shared index "customers" select customers
// -- It doesn't seem to allow updating a record without an rlock() if rlock() replace creditlim with 1000 unlock endif
bashmode:ON You need the RLock() (record lock) function due to shared mode. You can have multiple users trying to update the same record concurrently. If you opened the DBF in EXCLUSIVE mode, it would not be required. bashmode:OFF
Once you understand the functional/class handling way of DBF interfacing, you can shorten this code too. Look in the help file for DbServer etc. There are very few X# users that still do command based coding.
Another tip. If you set the commandline switch /ppo to be included in the compilation, you will see in the .prg folder a .ppo file created. If you open this you will see what the pre-processor did to your code to make the compiler understand your VFP XBase commands.
Johan
PS: By the way, are you using Visual Studio or XIDE for this work?
Hmm not sure about VFP recognizable, it looks quite X# to me... :-P
Well, in VFP I would have done:
use customers in 0 shared
I wouldn't need to specify the CDX as it would be opened automatically.
I could also do, in VFP:
if seek("ADA0001", "customers", "account") endif
or in fact:
update customers where account = "ADA0001" set creditlim = 1000
PS: By the way, are you using Visual Studio or XIDE for this work?
Visual Studio, as I am very familiar with it already.
Hi Alan,
On 2019/10/23 13:52, Alan Bourke wrote:
use customers in 0 shared I wouldn't need to specify the CDX as it would be opened automatically.
If I remember correctly, DBFCDX is AutoOpening CDX. Might be good to ask on the forums, Robert currently en-route to SWFOX, but Chris is monitoring.
Just need to confirm, there is also a SET AUTOOPEN True for default setting.
I could also do, in VFP:
if seek("ADA0001", "customers", "account") endif
X# contain the function DbSeek:
FUNCTION DbSeek( uKey AS USUAL, lSoftSeek AS USUAL, lLast AS USUAL ) AS LOGIC
This does the seek on the current order in the current workarea. If needed on a different workarea (OrderDetail):
IF OrderDetail->DbSeek("ADA0001")
or in fact:
update customers where account = "ADA0001" set creditlim = 1000
Update in X# is used when you want to update 1 workarea from another workarea. REPLACE is the similar command.
REPLACE <idField> WITH <uValue> [, <idField> WITH <uValue>...] [<Scope>] [WHILE <lCondition>]
[FOR <lCondition>] [[IN|ALIAS] <workarea>]
This is used as follow:
replace creditlim with 1000[, <rest>] for account = "ADA0001"
If you look at dbcmd.xh you will see a lot of these are actually handled by 1 internal function DbEval(), all the commands are pre-processed into variation of passed parameters.
FUNCTION DbEval( cbExecute AS USUAL, cbForCondition AS USUAL, cbWhileCondition AS USUAL, nNext AS USUAL, nRecord AS USUAL, lRest AS USUAL ) AS LOGIC
PS: By the way, are you using Visual Studio or XIDE for this work?
Visual Studio, as I am very familiar with it already.
Ok, you might want to at least check XIDE...
Johan
--- StripMime Report -- processed MIME parts --- multipart/alternative text/plain (text body -- kept) text/html ---
I'd just abandon learning this hybrid and use that time learning a better replacement. The code samples are walking on thin ice between how you use to do it in FOX and how you do it in any client/server environment.
Here is code to fetch a schedule of games for a team in a table that will show an image for each team as well as the event's data. In basic functionality, you get data, tweak it and pass it to be presented.
List<schedule> Schedule = db.schedules.ToList(); //Calls data from a view on the server foreach (schedule game in Schedule) { game.logolocation = "/icons/" + game.logolocation + ".jpg"; // Create the path for the team logo }
Schedule.Sort((x, y) => DateTime.Compare(x.eventDate, y.eventDate)); // Sort the schedule
return View("Index", Schedule); // bring it on home
On Wed, Oct 23, 2019 at 7:36 AM Johan Nel johan.nel@xsinet.co.za wrote:
Hi Alan,
On 2019/10/23 13:52, Alan Bourke wrote:
use customers in 0 shared I wouldn't need to specify the CDX as it would be opened automatically.
If I remember correctly, DBFCDX is AutoOpening CDX. Might be good to ask on the forums, Robert currently en-route to SWFOX, but Chris is monitoring.
Just need to confirm, there is also a SET AUTOOPEN True for default setting.
I could also do, in VFP:
if seek("ADA0001", "customers", "account") endif
X# contain the function DbSeek:
FUNCTION DbSeek( uKey AS USUAL, lSoftSeek AS USUAL, lLast AS USUAL ) AS LOGIC
This does the seek on the current order in the current workarea. If needed on a different workarea (OrderDetail):
IF OrderDetail->DbSeek("ADA0001")
or in fact:
update customers where account = "ADA0001" set creditlim = 1000
Update in X# is used when you want to update 1 workarea from another workarea. REPLACE is the similar command.
REPLACE <idField> WITH <uValue> [, <idField> WITH <uValue>...] [<Scope>] [WHILE <lCondition>]
[FOR <lCondition>] [[IN|ALIAS] <workarea>]
This is used as follow:
replace creditlim with 1000[, <rest>] for account = "ADA0001"
If you look at dbcmd.xh you will see a lot of these are actually handled by 1 internal function DbEval(), all the commands are pre-processed into variation of passed parameters.
FUNCTION DbEval( cbExecute AS USUAL, cbForCondition AS USUAL, cbWhileCondition AS USUAL, nNext AS USUAL, nRecord AS USUAL, lRest AS USUAL ) AS LOGIC
PS: By the way, are you using Visual Studio or XIDE for this work?
Visual Studio, as I am very familiar with it already.
Ok, you might want to at least check XIDE...
Johan
--- StripMime Report -- processed MIME parts --- multipart/alternative text/plain (text body -- kept) text/html
[excessive quoting removed by server]
Stephen,
I actually address this philosophical issue of the best use of your time in the conclusion of my Southwest Fox session, but it's a valid point. I conclude there are many use cases where the "hybrid" X# is a fine choice for transitioning from FoxPro to .Net.
Eric
On Wed, Oct 23, 2019 at 8:46 AM Stephen Russell srussell705@gmail.com wrote:
I'd just abandon learning this hybrid and use that time learning a better replacement. The code samples are walking on thin ice between how you use to do it in FOX and how you do it in any client/server environment.
Here is code to fetch a schedule of games for a team in a table that will show an image for each team as well as the event's data. In basic functionality, you get data, tweak it and pass it to be presented.
List<schedule> Schedule = db.schedules.ToList(); //Calls data from a view on the server foreach (schedule game in Schedule) { game.logolocation = "/icons/" + game.logolocation + ".jpg"; // Create the path for the team logo }
Schedule.Sort((x, y) => DateTime.Compare(x.eventDate, y.eventDate)); // Sort the schedule
return View("Index", Schedule); // bring it on home
On Wed, Oct 23, 2019 at 7:36 AM Johan Nel johan.nel@xsinet.co.za wrote:
Hi Alan,
On 2019/10/23 13:52, Alan Bourke wrote:
use customers in 0 shared I wouldn't need to specify the CDX as it would be opened automatically.
If I remember correctly, DBFCDX is AutoOpening CDX. Might be good to ask on the forums, Robert currently en-route to SWFOX, but Chris is monitoring.
Just need to confirm, there is also a SET AUTOOPEN True for default setting.
I could also do, in VFP:
if seek("ADA0001", "customers", "account") endif
X# contain the function DbSeek:
FUNCTION DbSeek( uKey AS USUAL, lSoftSeek AS USUAL, lLast AS USUAL ) AS LOGIC
This does the seek on the current order in the current workarea. If needed on a different workarea (OrderDetail):
IF OrderDetail->DbSeek("ADA0001")
or in fact:
update customers where account = "ADA0001" set creditlim = 1000
Update in X# is used when you want to update 1 workarea from another workarea. REPLACE is the similar command.
REPLACE <idField> WITH <uValue> [, <idField> WITH <uValue>...] [<Scope>] [WHILE <lCondition>]
[FOR <lCondition>] [[IN|ALIAS] <workarea>]
This is used as follow:
replace creditlim with 1000[, <rest>] for account = "ADA0001"
If you look at dbcmd.xh you will see a lot of these are actually handled by 1 internal function DbEval(), all the commands are pre-processed into variation of passed parameters.
FUNCTION DbEval( cbExecute AS USUAL, cbForCondition AS USUAL, cbWhileCondition AS USUAL, nNext AS USUAL, nRecord AS USUAL, lRest AS USUAL ) AS LOGIC
PS: By the way, are you using Visual Studio or XIDE for this work?
Visual Studio, as I am very familiar with it already.
Ok, you might want to at least check XIDE...
Johan
--- StripMime Report -- processed MIME parts --- multipart/alternative text/plain (text body -- kept) text/html
[excessive quoting removed by server]
I'd just abandon learning this hybrid and use that time learning a better replacement.
I've been developing in C# since .NET 1.1, so I've got that covered.
The code samples are walking on thin ice between how you use to do it in FOX and how you do it in any client/server environment.
For my own use case I would see a lot of value in quick conversions of VFP function libraries that don't necessarily interact with data, of which I have a lot.
Interesting comment there, " quick conversions of VFP function libraries"
I have to ask what functionality from VFP that you wanted in .NET? String manipulation, data manipulation or something else?
At work we have a C# shortcomings dll but that was written in 2007-9 days. We no longer use it but it is still there.
On Wed, Oct 23, 2019 at 9:46 AM Alan Bourke alanpbourke@fastmail.fm wrote:
I'd just abandon learning this hybrid and use that time learning a better replacement.
I've been developing in C# since .NET 1.1, so I've got that covered.
The code samples are walking on thin ice between how you use to do it in FOX and how you do it in any client/server environment.
For my own use case I would see a lot of value in quick conversions of VFP function libraries that don't necessarily interact with data, of which I have a lot.
-- Alan Bourke alanpbourke (at) fastmail (dot) fm
[excessive quoting removed by server]
On Wed, 23 Oct 2019, at 4:55 PM, Stephen Russell wrote:
Interesting comment there, " quick conversions of VFP function libraries"
I have to ask what functionality from VFP that you wanted in .NET? String manipulation, data manipulation or something else?
More accurately I meant 'libraries of utility functions which are currently written in VFP'. As opposed to 'VFP functionality that I want in .NET'.
On 2019/10/24 10:15, Alan Bourke wrote:
On Wed, 23 Oct 2019, at 4:55 PM, Stephen Russell wrote:
Interesting comment there, " quick conversions of VFP function libraries"
Matt Slay have shared a VFP-Toolkit for .NET that was developed about 10 years ago. Bringing those into X# is a mere reference inside your X# applications...
I have to ask what functionality from VFP that you wanted in .NET? String manipulation, data manipulation or something else?
More accurately I meant 'libraries of utility functions which are currently written in VFP'. As opposed to 'VFP functionality that I want in .NET'.
That library is available as above.
https://github.com/mattslay/XSharp.VFP/tree/master/VFP%20Toolkit%20for%20.Ne...
Again I appear to be failing in getting across what I am talking about.
I have lots of PRG files with classes and libraries that have no UI and usually no database interactions. They do line of business calculations, they do filesystem based things. Rather than rewrite them completely in C# it might be nice to rewrite them to a lesser extent in the VFP syntax of X#.
Hi Alan,
On 2019/10/24 12:57, Alan Bourke wrote:
Again I appear to be failing in getting across what I am talking about.
I have lots of PRG files with classes and libraries that have no UI and usually no database interactions. They do line of business calculations, they do filesystem based things. Rather than rewrite them completely in C# it might be nice to rewrite them to a lesser extent in the VFP syntax of X#.
Understood. Yes those are the easier ones to migrate actually.
Sounds dangerous, finding gaps between X#-C# and VFP with respect to filesystem functionality. If the Line of Business is really decorating the UI, will that still work?
On Thu, Oct 24, 2019 at 10:26 AM Johan Nel johan.nel@xsinet.co.za wrote:
Hi Alan,
On 2019/10/24 12:57, Alan Bourke wrote:
Again I appear to be failing in getting across what I am talking about.
I have lots of PRG files with classes and libraries that have no UI and
usually no database interactions. They do line of business calculations, they do filesystem based things. Rather than rewrite them completely in C# it might be nice to rewrite them to a lesser extent in the VFP syntax of X#. Understood. Yes those are the easier ones to migrate actually.
[excessive quoting removed by server]
On Wed, 23 Oct 2019 at 15:45, Alan Bourke alanpbourke@fastmail.fm wrote:
For my own use case I would see a lot of value in quick conversions of VFP function libraries that don't necessarily interact with data, of which I have a lot.
It would be interesting to see how a C# decompiler would cope with the XSharp generated bytecode. JetBrains has a free one (IIRC).
If XSharp was around 10 years ago I would have seriously considered it. We transitioned from XBase++ to C# Winforms (1000+ installs, still a few stubborn ones!) and have started a project to move to ASP.NET Core (and merging several apps acquired over the years).
Hi Paul,
On 2019/10/23 19:48, Paul Hill wrote:
On Wed, 23 Oct 2019 at 15:45, Alan Bourke alanpbourke@fastmail.fm wrote:
For my own use case I would see a lot of value in quick conversions of VFP function libraries that don't necessarily interact with data, of which I have a lot.
It would be interesting to see how a C# decompiler would cope with the XSharp generated bytecode. JetBrains has a free one (IIRC).
Well ILSpy is also free and even have a X# Language plugin, it can convert c# code even to X#. Same with taking X# assemblies and "translate" to c#.
If XSharp was around 10 years ago I would have seriously considered it. We transitioned from XBase++ to C# Winforms (1000+ installs, still a few stubborn ones!) and have started a project to move to ASP.NET Core (and merging several apps acquired over the years).
Well X# has language syntax support for XBase++, so maybe those stubborn ones can be ported to X# and get compiled without (m)any changes....
Johan.
Hi Stephen,
On 2019/10/23 15:46, Stephen Russell wrote:
I'd just abandon learning this hybrid and use that time learning a better replacement. The code samples are walking on thin ice between how you use to do it in FOX and how you do it in any client/server environment.
I realize your sentiments. However, there are still many people that have not done the migration "learning curve" to .NET
It is easy to state a hybrid environment. X# is definitely not a "hybrid" environment. It is build on exactly the same platform as c# the Roslyn project.
Hence, it is a migration platform supporting XBase style commands. But under the hood it is actually c# in XBase syntax.
Here is code to fetch a schedule of games for a team in a table that will show an image for each team as well as the event's data. In basic functionality, you get data, tweak it and pass it to be presented.
Yes and line for line without the funny "{};" c# each line can be converted to pure X#.NET code:
var Schedule = db.schedules.ToList() //Calls data from a view
on the server
foreach local game as schedule in Schedule game.logolocation = "/icons/" + game.logolocation + ".jpg" // Create the path for the team logo next // endfor if you prefer VFP syntax Schedule.Sort({x, y => DateTime.Compare(x.eventDate, y.eventDate) // Sort the schedule return View("Index", Schedule) // bring it on home })
On top of that. Throw this at the X# compiler, open ILSpy and you will see that code written in c#. Add the ILSpy X# language plug-in and take any c# assembly and view it as if was written in X#. Save this from ILSpy and voila out comes a Visual Studio X# solution.
Definitely not a "hybrid" environment. Except maybe for USE/SKIP/GOTOP etc. that X# understand but c# will choke on... But via ILSpy even these can be understood by c#.
Just my 2c.
Johan
Thank you for the explanation of the underlying concept of the core functionality presented via X#.
My current codebase when I write C# code is usually MVC in nature and I use a good deal of lambda syntax nowadays.
On Wed, Oct 23, 2019 at 4:59 PM Johan Nel johan.nel@xsinet.co.za wrote:
Hi Stephen,
On 2019/10/23 15:46, Stephen Russell wrote:
I'd just abandon learning this hybrid and use that time learning a better replacement. The code samples are walking on thin ice between how you
use
to do it in FOX and how you do it in any client/server environment.
I realize your sentiments. However, there are still many people that have not done the migration "learning curve" to .NET
It is easy to state a hybrid environment. X# is definitely not a "hybrid" environment. It is build on exactly the same platform as c# the Roslyn project.
Hence, it is a migration platform supporting XBase style commands. But under the hood it is actually c# in XBase syntax.
Here is code to fetch a schedule of games for a team in a table that will show an image for each team as well as the event's data. In basic functionality, you get data, tweak it and pass it to be presented.
Yes and line for line without the funny "{};" c# each line can be converted to pure X#.NET code:
var Schedule = db.schedules.ToList() //Calls data from a view
on the server
foreach local game as schedule in Schedule game.logolocation = "/icons/" + game.logolocation + ".jpg" // Create the path for the team logo next // endfor if you prefer VFP syntax Schedule.Sort({x, y => DateTime.Compare(x.eventDate, y.eventDate) // Sort the schedule return View("Index", Schedule) // bring it on home })
On top of that. Throw this at the X# compiler, open ILSpy and you will see that code written in c#. Add the ILSpy X# language plug-in and take any c# assembly and view it as if was written in X#. Save this from ILSpy and voila out comes a Visual Studio X# solution.
Definitely not a "hybrid" environment. Except maybe for USE/SKIP/GOTOP etc. that X# understand but c# will choke on... But via ILSpy even these can be understood by c#.
Just my 2c.
Johan
[excessive quoting removed by server]