Monthly Archives: April 2006

DOS Reports using Foxpro 2.6

The code below i believe is useful in my program.

if (System.IO.File.Exists("d:\pepesfile\rd-png\fpd26\foxprox.exe" ))
{
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.WorkingDirectory = "d:\pepesfile\rd-png\hrdpayroll\";
proc.StartInfo.FileName = "d:\pepesfile\rd-png\fpd26\foxprox.exe";
proc.StartInfo.Arguments = "main.app";
proc.Start();
}
else
{
System.Windows.Forms.MessageBox.Show("Wala...");
}

Shell Commands within C#

I’ve found this interesting article on .net..I believe I’ve once tried this in my program but for the sake of recording this one, I’m posting it here.

In this article we will examine a few examples for executing shell commands outside of our program using C#. In VB.Net, we can make use of the familiar Shell command to run an executable program. However the Shell function is not available in C#. The Process Class provides access to local and remote processes and enables you to start and stop local system processes.

In our example we will create an example for running the following processes from our program.
1. Calculator
2. DOS Batch program – Map a network drive
3. Internet explorer with a specified URL
4. Specified Document in Microsoft Word.

C# Application
Our basic application is a Winforms Visual C# application and will consist of a Windows Form with button controls to invoke the processes specified in the list. (The complete code for the application is provided at the bottom of the article).

Add button controls from the toolbox as shown in the figure below.

Figure 1: Basic Windows Form
calculator

Calculator

The option to provide a calculator to the end user on the click of a button can be very useful. The calculator program can be invoked from command line using the command “calc”.

Add the following code to the event handler for the button’s Click event as shown below. Details explaining the code follow the code listing.

System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents=false;
proc.StartInfo.FileName=”calc”;
proc.Start();
Code Listing: Invoke the calculator from a C# program

We create a new Process and assign the FileName variable to the name of the executable that we want to run. The Start() method of the Process object starts the specified application and assigns it to the process component.

Figure: Calculator is invoked when the Calculator button is clicked.
calcu
Map a network Drive

We will invoke a DOS batch script which will map a network drive for us. The DOS command for mapping a drive is as follows:

NET USE : \ /User: /PERSISTENT:YES

Note : Ensure that the drive mapping is not already in use.

Create a text file containing the above command and Save the file as netdrv.bat. I saved the file in folder c:dotnetstuffnetdrv.bat.

Here is the format of the command contained in the netdrv.bat file.

NET USE U: \mastertestshare /User:Enterprisedchoksi passwd /PERSISTENT:YES

Add the following code to the button click event handler of the button labeled “Map Network Drive”.

System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents=false;
proc.StartInfo.FileName=”c:\dotnetstuff\netdrv.bat”;
proc.Start();
MessageBox.Show(“Map Drive Created”);

Code Listing: This code will execute the dos batch file and U: is mapped to the remote share \mastertestshare.

Microsoft.com

We will create a button that will take the user to the Microsoft.com web site. This logic can be used to open up a registration form for product registration or to point to online help in Windows forms products.

Add the following code in the button Click event handler

System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents=false;
proc.StartInfo.FileName=”iexplore”;
proc.StartInfo.Arguments=”http://www.microsoft.com”;
proc.Start();
proc.WaitForExit();
MessageBox.Show(“You have just visited www.microsoft.com”);

Code Listing: Microsoft.com

Note that the code waits for the Internet Explorer process to exit and then proceeds to display the messagebox. This is achieved through the use of the WaitForExit() function of the Process object.

Open a specific document in Microsoft Word

Add the following code to the button’s OnClick event handler.

System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents=false;
proc.StartInfo.FileName=”winword”;
proc.StartInfo.Arguments=”C:\Dotnetstuff\TestWordDoc.doc”;
proc.Start();

Code Listing : Open specific Word Document

Note that the name of the Word document to open is specified in the Arguments for the StartInfo of the Process.
Complete Code Listing:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace ShellCS_NS
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.Button button4;

public Form1()
{
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.button3 = new System.Windows.Forms.Button();
this.button4 = new System.Windows.Forms.Button();
this.SuspendLayout();

this.button1.Location = new System.Drawing.Point(16, 24);
this.button1.Name = “button1”;
this.button1.Size = new System.Drawing.Size(112, 72);
this.button1.TabIndex = 0;
this.button1.Text = “Calculator”;
this.button1.Click += new System.EventHandler(this.button1_Click);

this.button2.Location = new System.Drawing.Point(16, 120);
this.button2.Name = “button2”;
this.button2.Size = new System.Drawing.Size(112, 72);
this.button2.TabIndex = 1;
this.button2.Text = “Map Network Drive”;
this.button2.Click += new System.EventHandler(this.button2_Click);

this.button3.Location = new System.Drawing.Point(168, 24);
this.button3.Name = “button3”;
this.button3.Size = new System.Drawing.Size(112, 72);
this.button3.TabIndex = 2;
this.button3.Text = “Microsoft.com”;
this.button3.Click += new System.EventHandler(this.button3_Click);

this.button4.Location = new System.Drawing.Point(168, 120);
this.button4.Name = “button4”;
this.button4.Size = new System.Drawing.Size(112, 64);
this.button4.TabIndex = 3;
this.button4.Text = “My Word Document”;
this.button4.Click += new System.EventHandler(this.button4_Click);

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 213);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.button4, this.button3, this.button2, this.button1});
this.Name = “Form1”;
this.Text = “Form1″;
this.ResumeLayout(false);
}

protected override void Dispose( bool disposing )
{
base.Dispose( disposing );
}
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

private void button1_Click(object sender, System.EventArgs e)
{
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents=false;
proc.StartInfo.FileName=”calc”;
proc.Start();
}

private void button2_Click(object sender, System.EventArgs e)
{
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents=false;
proc.StartInfo.FileName=”c:\dotnetstuff\NETDRV.bat”;
proc.Start();
MessageBox.Show(“Map Drive Created”);
}

private void button3_Click(object sender, System.EventArgs e)
{

System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents=false;
proc.StartInfo.FileName=”iexplore”;
proc.StartInfo.Arguments=”http://www.microsoft.com”;
proc.Start();
proc.WaitForExit();
MessageBox.Show(“You have just visited www.microsoft.com”);
}

private void button4_Click(object sender, System.EventArgs e)
{
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents=false;
proc.StartInfo.FileName=”winword”;
proc.StartInfo.Arguments=”C:\Dotnetstuff\TestWordDoc.doc”;
proc.Start();
}
}
}

Code Listing: Shellcs.cs

NET USE U: \mastertestshare /User:Enterprisedchoksi passwd /PERSISTENT:YES

Code Listing : Netdrv.bat

Disabling the Cell in Datagrid

Though I’ve already created a program for this in the QCS of Purchasing, I opt to review the code which I’ve written before…In the Production progs, a feature was request by my colleague and I’ve program this


Public Class DatagridCellxCellEnable
Inherits DataGridTextBoxColumn
Private _col As Integer
Public Sub New(ByVal column As Integer)
MyBase.New()
_col = column
End Sub
Public Delegate Sub EnableCellEventHandler(ByVal sender As Object, ByVal e As DataGridEnableEventArgs)
'
Public Event CheckCellEnabled As EnableCellEventHandler
Protected Overloads Overrides Sub Edit(ByVal source As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal bounds As System.Drawing.Rectangle, ByVal [readOnly] As Boolean, ByVal instantText As String, ByVal cellIsVisible As Boolean)
Dim enabled As Boolean
enabled = True
Dim e As DataGridEnableEventArgs
e = New DataGridEnableEventArgs(rowNum, _col, enabled)
RaiseEvent CheckCellEnabled(Me, e)
If e.EnableValue Then
MyBase.Edit(source, rowNum, bounds, [readOnly], instantText, cellIsVisible)
End If
End Sub
'
End Class

In my code i’ve included this


Dim numCols As Integer = Me.dtProdVolume.Columns.Count
Do While (i < numCols) Dim aColumnTextColumn As DatagridCellxCellEnable aColumnTextColumn = New DatagridCellxCellEnable(i) aColumnTextColumn.MappingName = Me.dtProdVolume.Columns(i).ColumnName AddHandler aColumnTextColumn.CheckCellEnabled, _ New DatagridCellxCellEnable.EnableCellEventHandler(AddressOf SetEnableValues) tableStyle.GridColumnStyles.Add(aColumnTextColumn) i = i + 1 Loop

an example c# code for this is available here

Foxpro 2.0 : Numeric to Words Converter


* FUNCTION N2W.PRG
* As typed in from a PC Magazine awhile back (can't find the issue)
* Uploaded to library for general use
* Converts numbers to text
PARAMETERS nVar, cCurrency, lChecktype
IF PARAMETERS() = 0 OR !TYPE('nVar')=='N'
RETURN 'Not a valid request'
ENDIF
IF PARAMETERS() = 1 OR TYPE('cCurrency')<>'C'
cCurrency = '$'
ENDIF
IF PARAMETERS() > 2
lChecktype = .T.
ENDIF
nStr = ALLTRIM(STR(nVar,20,2))
nLen = LEN(nStr)
noclass = CEILING(nlen/3)
nlen = noclass * 3
nstr = PADL(nstr, nlen)
num2word = ''
DECLARE nword[nlen], nvalue[nlen]
FOR i = 1 TO nlen STEP 1
nvalue[i] = SUBSTR(nstr, nlen-i+1,1)
nword[i] = ''
ENDFOR
* Step 1: parse each number according to its
* *
FOR nbit = 1 TO nlen STEP 1
checkbit = RIGHT('00'+LTRIM(STR(nbit)),2)
DO CASE
CASE INLIST(checkbit,'01','04','07','10','13','16')
DO unitshunds
CASE INLIST(checkbit,'02','05','08','11','14','17')
DO tens
CASE INLIST(checkbit,'03','06','09','12','15','18')
DO unitshunds
ENDCASE
ENDFOR
* Step 2: parse each number according to its sequence
* and group accordingly
*
DECLARE class[noclass]
FOR i = 1 TO noclass
STORE '' TO class[i]
ENDFOR
FOR i = 2 TO noclass
IF !EMPTY(nword(3*i))
class[i] = nword(3*i) + ' Hundred'
ENDIF
class[i] = ALLTRIM(class[i]) + ;
IIF(!ALLTRIM(nword(3*i-1))=='',' ','') + ;
ALLTRIM(nword(3*i-1))
IF !nvalue(3*i-1) = '1'
DO CASE
CASE !ALLTRIM(nword(3*i-1))=='' AND !ALLTRIM(nvalue(3*i-2))='0'
class[i] = ALLTRIM(class[i]) + '-' + ALLTRIM(nword(3*i-2))
CASE ALLTRIM(nword(3*i-1))=='' AND !ALLTRIM(nvalue(3*i-2))='0'
class[i] = ALLTRIM(class[i]) + ' ' + ALLTRIM(nword(3*i-2))
ENDCASE
ENDIF
class[i] = ALLTRIM(class[i])
DO CASE
CASE i = 6
class[i] = IIF(!EMPTY(class[i]), class[i]+' Trillion, ','')
CASE i = 5
class[i] = IIF(!EMPTY(class[i]), class[i]+' Billion, ','')
CASE i = 4
class[i] = IIF(!EMPTY(class[i]), class[i]+' Million, ','')
CASE i = 3
class[i] = IIF(!EMPTY(class[i]), class[i]+' Thousand, ','')
ENDCASE
num2word = class[i] + num2word
ENDFOR
IF RIGHT(ALLTRIM(num2word),1) = ','
num2word = LEFT(ALLTRIM(num2word), LEN(ALLTRIM(num2word))-1)
ENDIF
dec2word = nword(2)
IF !nvalue(2) = '1'
dec2word = dec2word + ;
IIF(!ALLTRIM(nword(2))=='' AND ;
!ALLTRIM(nvalue(1))='0','-','')+;
nword(1)
ENDIF
dec2word = ALLTRIM(dec2word)
STORE '' TO nat_bcurr, nat_scurr
num2word = IIF(ALLTRIM(num2word)=='','Zero',num2word)
dec2word = IIF(ALLTRIM(dec2word)=='','Zero',dec2word)
num2word = IIF(nVar < 0, 'Minus '+num2word, num2word) IF UPPER(cCurrency)=='NUM' RETURN ; IIF(dec2word=='Zero', num2word, num2word+' Point '+dec2word) ENDIF * Step 3: add currency if requested * DO curr2word num2word = num2word + ' ' + nat_bcurr dec2word = dec2word + ' ' + nat_scurr IF lChecktype && use 99/100 check format dec2word = ALLTRIM(nvalue[2])+ALLTRIM(nvalue[1])+'/100' ENDIF RETURN num2word + IIF(!ALLTRIM(dec2word)=='',' and ','')+dec2word * -- PROCEDURE unitshunds DO CASE CASE nvalue(nbit) = '1' nword(nbit) = 'One' CASE nvalue(nbit) = '2' nword(nbit) = 'Two' CASE nvalue(nbit) = '3' nword(nbit) = 'Three' CASE nvalue(nbit) = '4' nword(nbit) = 'Four' CASE nvalue(nbit) = '5' nword(nbit) = 'Five' CASE nvalue(nbit) = '6' nword(nbit) = 'Six' CASE nvalue(nbit) = '7' nword(nbit) = 'Seven' CASE nvalue(nbit) = '8' nword(nbit) = 'Eight' CASE nvalue(nbit) = '9' nword(nbit) = 'Nine' ENDCASE RETURN * -- PROCEDURE tens DO CASE CASE nvalue(nbit) = '1' DO CASE CASE nvalue(nbit-1) = '0' nword(nbit) = 'Ten' CASE nvalue(nbit-1) = '1' nword(nbit) = 'Eleven' CASE nvalue(nbit-1) = '2' nword(nbit) = 'Twelve' CASE nvalue(nbit-1) = '3' nword(nbit) = 'Thirteen' CASE nvalue(nbit-1) = '4' nword(nbit) = 'Fourteen' CASE nvalue(nbit-1) = '5' nword(nbit) = 'Fifteen' CASE nvalue(nbit-1) = '6' nword(nbit) = 'Sixteen' CASE nvalue(nbit-1) = '7' nword(nbit) = 'Seventeen' CASE nvalue(nbit-1) = '8' nword(nbit) = 'Eighteen' CASE nvalue(nbit-1) = '9 nword(nbit) = 'Nineteen' ENDCASE CASE nvalue(nbit) = '2' nword(nbit) = 'Twenty' CASE nvalue(nbit) = '3' nword(nbit) = 'Thirty' CASE nvalue(nbit) = '4' nword(nbit) = 'Forty' CASE nvalue(nbit) = '5' nword(nbit) = 'Fifty' CASE nvalue(nbit) = '6' nword(nbit) = 'Sixty' CASE nvalue(nbit) = '7' nword(nbit) = 'Seventy' CASE nvalue(nbit) = '8' nword(nbit) = 'Eighty' CASE nvalue(nbit) = '9' nword(nbit) = 'Ninety' ENDCASE RETURN * -- PROCEDURE curr2word STORE .T. TO s_breq, s_sreq STORE UPPER(cCurrency) TO cCurrency DO CASE CASE (cCurrency) = '$' OR 'USA' $ UPPER(cCurrency) nat_bcurr = 'Dollar' nat_scurr = 'Cent' CASE (cCurrency) = 'œ' OR 'GRB' $ UPPER(cCurrency) * œ is chr(156) nat_bcurr = 'Pound' nat_scurr = 'Pence' s_sreq = .F. CASE (cCurrency) = '' OR 'JPN' $ UPPER(cCurrency) *  is chr(157) nat_bcurr = '' nat_scurr = 'Yen' STORE .F. TO s_breq, s_sreq CASE (cCurrency) = 'N' OR 'NGR' $ UPPER(cCurrency) nat_bcurr = 'Naira' nat_scurr = 'Kobo' STORE .F. TO s_breq, s_sreq * Add other countries here... OTHERWISE nat_bcurr = 'Dollar' nat_scurr = 'Cent' ENDCASE nat_bcurr = IIF(!ALLTRIM(num2word)=='', ; IIF(nvalue(4)='1' AND num2word=='One', nat_bcurr, nat_bcurr+; IIF(s_breq, 's', '')),'') nat_scurr = IIF(!ALLTRIM(dec2word)=='', ; IIF(nvalue(1)='1' AND dec2word=='One', nat_scurr, nat_scurr+; IIF(s_sreq, 's', '')),'') RETURN .T. * eof: n2w.prg * ------------------

More on SQLite Backend Discussion

I found some odd instruction in the SQLite 3.0 version.
The following works properly in PostgreSQL

SELECT * FROM totp WHERE wk BETWEEN DATE '1980-05-20'
AND DATE '1980-05-26'

and its equivalent in MS SQL is :

SELECT * FROM totp WHERE wk BETWEEN '1980-05-20'
AND '1980-05-26'

while on the SQLite its equivalent of this is :

SELECT * FROM totp WHERE wk BETWEEN date('1980-05-20')
AND date('1980-05-26')

Notes on SQLite Data Provider

I’m using Finisar namespace as my data provider for SQLite Database in the Timecard program. The only problem I have is that unlike the other database managers like Postgresql, Mysql and MS SQL, it doesn’t have an inherent date computation program.

If my solution wont work, I will then resort to ADO.net and row by row I’ll compute the interval of each date on that data.

This is the result of the new code. More complex than the normal coding in SQL Server, but I guess it solves my problem.
sqlite> select (strftime('%s',pmend)-strftime('%s',pmstart))/3600 as t1,pmstart,pmend from vwdtsdetail where dtsdetailid= 20;
5.5|2006-04-19 13:00:00|2006-04-19 18:30:00

Another thing that i observed in sqlite is that the function strftime wont work if the datetime format doesn’t appear like this : yyyy-MM-dd HH:mm:ss
and the date format is : yyyy-MM-dd

My Problem in Datagrid

This has been my problem since I’ve started developing the system. This error keeps on displaying on my program. I dont know how to solve this though I’ve keep on researching on this one. Maybe this one has been solve on the .net 2005 release. Hopefully….

On using sqlite as a backend

Medical History Recorder Pics

This program was revived last week. I’ve decided to use SQLite as its backend database. Doc told me that its too slow to access from her computer to my Linux server. The first backend of this one is the Postgresql. I’ve decided to use my newly bought Corelab Postgresql database provider, I’m still in doubt before of the capability of the native ado.net provider of Postgresql (npgsql) that time. Now the Npgsql of Postgresql is in its stable version. But anyways the corelab itself keeps on updating their version of their provider. I like the postgresql though mysql is very popular, I tend to prefer the postgresql (though this blog also uses mysql 🙂 )