Made many changes. Please test if you can
provide me feedback. Thanks.
PS If you don't see END SCRIPT, then some code was truncated.
Eric
CHANGES BELOW:
#---------------------------------------------------------------------
# Name: dbscrollgrid.pl
#
# Purpose: Database Scroll Cursor Grid (Perl Win32::ODBC,GUI)
#
# Author: Eric Hansen, Copyright 1999, Information
# Technology Services, Inc. Dallas, TX
#
# Contact: [EMAIL PROTECTED]
#
# Description: Display an ODBC SQL result set in a GUI database grid
# allowing the user to navigate back and forth throughout
# the result set. This script uses a scroll cursor on
# the database. Large SQL result sets may be navigated
# in this way. 100 rows maximum are loaded to the grid
# from the result set at any one time.
#
# Required: Your ODBC driver must support scrolling cursors.
# You must configure your DSN to enable scrolling cursors.
# i.e. Informix Driver has a checkbox you must check
# to enable scrolling cursors.
# You must have installed the Perl Win32::GUI package.
# Assign your DSN to the $DSN variable below.
#---------------------------------------------------------------------
$DSN="pnetdss_cdi"; # change the DataSourceName(DSN) here!
#---------------------------------------------------------------------
use Win32::GUI;
use Win32::ODBC;
# Hide the Dos Window
($DOShwnd, $DOShinstance) = GUI::GetPerlWindow();
GUI::Hide($DOShwnd);
#-------------------------#
# Window Controls
#-------------------------#
$Font = new GUI::Font(
-name => "Tahoma",
-size => 8,
-weight => 700,
-height => -11,
);
$W = new GUI::DialogBox(
-name => "Window",
-font => $Font,
-text => "dbscrollgrid.pl - Database Scroll Grid (Win32::ODBC,Win32::GUI)",
-width => 700,
-height => 550,
-left => 50,
-top => 20,
);
$W2 = new GUI::DialogBox(
-owner => $W,
-name => "Window2",
-font => $Font,
-text => "Enter a Row Number to Goto",
-width => 235,
-height => 150,
-style => ws_sysmenu,
-left => 300,
-top => 200,
);
$W2->Disable();
$W2->Hide();
$GotoBox = $W2->AddTextfield(-name => "GotoBox",
-font => $Font,
-width => 60,
-height => 20,
-group => 1,
-tabstop => 1,
-background => [255,255,255],
-foreground => [80,80,255],
-left => 65,
-top => 50,
);
$GotoBox->SendMessage(197, 7, 0); # limit to 7 character input
$OK = $W2->AddButton(-name => "OK",
-text => "OK",
-font => $Font,
-group => 1,
-tabstop => 1,
-width => 25,
-height => 18,
-left => 135,
-top => 50,
);
$Status = new GUI::StatusBar($W,
-text => " ",
-font => $Font,
-width => $W->ScaleWidth,
);
$LV = new GUI::ListView($W,
-name => "ListView",
-font => $Font,
-left => 10,
-top => 10,
-group => 1,
-tabstop => 1,
-width => $W->ScaleWidth-20,
-height => $W->ScaleHeight-140,
);
$LV->TextColor(hex("0000FF")); # red
$LV->View(1); # detailed listing
$First = $W->AddButton(-name => "First",
-font => $Font,
-group => 1,
-tabstop => 1,
-text => "First",
-width => 45,
-height => 18,
-left => 15,
-top => 404,
);
$First->Disable();
$Prev = $W->AddButton(-name => "Prev",
-font => $Font,
-group => 1,
-tabstop => 1,
-text => "Prev",
-width => 45,
-height => 18,
-left => 15,
-top => 424,
);
$Prev->Disable();
$Next = $W->AddButton(-name => "Next",
-font => $Font,
-group => 1,
-tabstop => 1,
-text => "Next",
-width => 45,
-height => 18,
-left => 15,
-top => 444,
);
$Next->Disable();
$Goto = $W->AddButton(-name => "Goto",
-font => $Font,
-group => 1,
-tabstop => 1,
-text => "Goto",
-width => 45,
-height => 18,
-left => 15,
-top => 464,
);
$Goto->Disable();
$Last = $W->AddButton(-name => "Last",
-font => $Font,
-group => 1,
-tabstop => 1,
-text => "Last",
-width => 45,
-height => 18,
-left => 15,
-top => 484,
);
$Last->Disable();
$SqlText = $W->AddRichEdit(-name => "SqlText",
-text => "Enter an SQL Statement here, then click 'Go Sql'",
-font => $Font,
-group => 1,
-tabstop => 1,
-width => 560,
-height => 100,
-left => 70,
-style => WS_VISIBLE | ES_MULTILINE | WS_TABSTOP,
-top => 402,
);
$SqlText->SendMessage(197, 1024, 0); # limit to 1024 character input
$SqlGo = $W->AddButton(-name => "SqlGo",
-font => $Font,
-group => 1,
-tabstop => 1,
-text => "Go Sql",
-width => 45,
-height => 18,
-left => 635,
-top => 440,
);
#----------------------------#
# Window Dialog
#----------------------------#
$W->Show;
Connect_To_Database();
GUI::Dialog;
#----------------------------#
# Non-Event Subroutines
#----------------------------#
END {
if ($db) {$db->Close();}
GUI::Show($DOShwnd);
}
sub Connect_To_Database {
$Status->Text("Connecting to Database...");
$Status->Update;
sleep 1;
$db = new ODBC($DSN);
if (! $db) {
GUI::MessageBox($W,"Can't Establish Database Connection to DSN '$DSN'",
"Error",16,);
GUI::MessageBox($W,"Shutting Down the Application","Status",64,);
exit;
}
$Status->Text("DataSourceName=$DSN");
$Status->Update;
$SqlText->SetFocus();
$SqlText->Select(0,length($SqlText->Text()));
}
sub Execute_SQL {
$LV->Clear();
$Status->Text("Running SQL Statement...");
$Status->Update;
sleep 1;
$sqltxt=$SqlText->Text();
$ret = $db->Sql($sqltxt);
$Status->Text("DataSourceName=$DSN");
$Status->Update;
}
sub Load_Table_Column_Headings {
$Status->Text("Loading Column Headings to Grid...");
$Status->Update;
sleep 1;
$LV->InsertColumn(-index => 0,-width => 50, -text => "Row#");
@Cols = $db->FieldNames();
$lastcol=$#Cols;
for($i=0;$i<$lastcol;$i++) {
$columname=$Cols[$i];
$LV->InsertColumn(-index => ($i+1),-width => 100, -text => $columname);
}
$Status->Text("DataSourceName=$DSN");
$Status->Update;
}
sub Load_Table_Data {
$Status->Text("Loading Database Grid...");
$Status->Update;
$itemcnt=0;
$rowcnt=$db->GetStmtOption($db->SQL_ROW_NUMBER());
$LV->InsertItem(-item => $itemcnt, -text => $rowcnt);
@Data=(); # clear the data array
@Data = $db->Data();
$lastfld=$#Data;
$subitemcnt=1;
for($i=0;$i<$lastfld;$i++) {
$fieldvalue=$Data[$i];
$LV->SetItem(-item => $itemcnt,
-subitem => $subitemcnt,
-text => $fieldvalue,
);
$subitemcnt++;
}
$itemcnt++;
while ($db->FetchRow()) {
$rowcnt=$db->GetStmtOption($db->SQL_ROW_NUMBER());
$LV->InsertItem(-item => $itemcnt, -text => $rowcnt);
@Data=(); # clear the data array
@Data = $db->Data();
$lastfld=$#Data;
$subitemcnt=1;
for($i=0;$i<$lastfld;$i++) {
$fieldvalue=$Data[$i];
$LV->SetItem(-item => $itemcnt,
-subitem => $subitemcnt,
-text => $fieldvalue,
);
$subitemcnt++;
}
$itemcnt++;
if ($itemcnt == 100) {last;}
}
if ($itemcnt < 100) {
$db->FetchRow(0,SQL_FETCH_LAST);
$rowcnt=$db->GetStmtOption($db->SQL_ROW_NUMBER());
}
$Status->Text("DataSourceName=$DSN");
$Status->Update;
}
sub Adjust_Cursor {
$rowcnt=$db->GetStmtOption($db->SQL_ROW_NUMBER());
$pos=($rowcnt % 100);
if ($rowcnt > 100) {
$pos=($rowcnt % 100);
if ($pos == 0) {$pos=100;}
$pos -= 1;
$db->FetchRow(($pos * -1),SQL_FETCH_RELATIVE);
}
else {
$db->FetchRow(0,SQL_FETCH_FIRST);
}
}
sub Verify_Pos {
if ($pos=~/^[0-9]+$/) {;} # must be all digits
else {return 1;}
if ($pos == 0) {return 1;}
return 0;
}
#----------------------------#
# Window Events
#----------------------------#
sub Window_Terminate {
if ($db) {$db->Close();}
GUI::Show($DOShwnd);
exit;
}
sub First_Click {
$LV->Clear();
$Status->Text("Fetching First Rowset...");
$Status->Update;
sleep 1;
$db->FetchRow(0,SQL_FETCH_FIRST);
Load_Table_Data();
}
sub Prev_Click {
$LV->Clear();
$Status->Text("Fetching Previous Rowset...");
$Status->Update;
sleep 1;
if ($rowcnt > 200) {
$pos=($rowcnt % 100);
if ($pos == 0) {$pos=199;}
else {$pos += 99;}
$db->FetchRow(($pos * -1),SQL_FETCH_RELATIVE);
}
else {
$Status->Text("Fetching First Rowset...");
$Status->Update;
sleep 1;
$db->FetchRow(0,SQL_FETCH_FIRST);
}
Load_Table_Data();
}
sub Next_Click {
$LV->Clear();
$Status->Text("Fetching Next Rowset...");
$Status->Update;
sleep 1;
if (! $db->FetchRow()) {
Last_Click();
}
else {
Load_Table_Data();
}
}
sub Last_Click {
$LV->Clear();
$Status->Text("Fetching Last Rowset...");
$Status->Update;
sleep 1;
$db->FetchRow(0,SQL_FETCH_LAST);
Adjust_Cursor();
Load_Table_Data();
}
sub Goto_Click {
$W->Disable();
$W2->Show();
$W2->Enable();
$GotoBox->SetFocus();
$GotoBox->Select(0,length($GotoBox->Text()));
}
sub OK_Click {
$pos=$GotoBox->Text();
if (Verify_Pos()) {
GUI::MessageBox($W2,"Enter a positve integer > 0","Error",16,);
$GotoBox->SetFocus();
$GotoBox->Select(0,length($GotoBox->Text()));
return;
}
$LV->Clear();
$W->Enable();
$W2->Hide();
$W2->Disable();
$Status->Text("Fetching Rowset with Row ($pos) ...");
$Status->Update;
sleep 2;
if (! $db->FetchRow($pos,SQL_FETCH_ABSOLUTE)) {
$Status->Text("Fetching Current Rowset Instead ...");
$Status->Update;
sleep 2;
$db->FetchRow($rowcnt,SQL_FETCH_ABSOLUTE);
}
Adjust_Cursor;
Load_Table_Data();
}
sub SqlGo_Click {
$First->Disable();
$Prev->Disable();
$Next->Disable();
$Goto->Disable();
$Last->Disable();
$db->DropCursor();
$db->SetStmtCloseType(SQL_DONT_CLOSE);
$db->SetStmtOption($db->SQL_CURSOR_TYPE,$db->SQL_CURSOR_STATIC);
Execute_SQL();
if ($ret != 0) {
$error=$db->Error(); # database error msg
Win32::GUI::MessageBox($W,$error,"SQL Error",16,);
$SqlText->SetFocus();
$SqlText->Select(0,length($SqlText->Text()));
return;
}
Load_Table_Column_Headings();
First_Click();
$First->Enable();
$Prev->Enable();
$Next->Enable();
$Goto->Enable();
$Last->Enable();
}
# END SCRIPT