Wednesday, August 31, 2005

A Look at PCI Express - Page 1: "Introduction

The venerable PCI Bus has been one of the bastions in PC connectivity for roughly a decade now. The limitations of the PCI bus was first highlighted with the introduction of the ubiquitous AGP port back in the summer of 1997.

The main advantages of AGP are its increased bus speed / bandwidth as well as its point to point architecture. A point to point protocol means that AGP has its own path way to communicate with the processor as well as one to the memory whereas every device on the PCI bus had to share the 133 MB/s worth of bandwidth allocated to it. Both the AGP and PCI Bus are based on a 32 bit bus. AGP being clocked at 66 Mhz versus 33 for PCI had double the bandwidth (266 MB/s) in its first iteration. With the ability to transfer data multiple times per clock cycle, AGP in recent times (currently at a maximum of 8x, has ~2100MB/s of bandwith).

With a bevy of high speed I/O devices today outside of the graphics card including SATA / ATA150 (150 MB/s), Gigabyte Ethernet (125 MB/s), 1394B (100 MB/s) it is easy to see that any one of these devices alone can completely saturate the PCI bus completely. Nearly everything else in the PC has scaled in one way or another in the past decade except for the PCI bus. With the exception of PCI-X (a 64 bit, 66 Mhz, server solution), the PCI bus has stayed relatively stagnant while many of the subsystems have been scaling up (frontside bus speed, memory, AGP). Fortunately, this is about to change with the advent of PCI Express.
PCI Express

PCI Express (not to be confused with PCI-X) is the upcoming replacement for both PCI and AGP. A couple of main points about PCI Express

* While the classic PCI Bus is based upon a parallel architecture, PCI Express is serial based, drastically reducing pin count.
* It is a point to point protocol much like AGP. Devices do not share bandwidth"

ajax

requester.onreadystatechange = managestatechange;
requester.open("GET", "../phpscript/ajax_query.php?part_no=" + part,true);
requester.send(null);
return return_value;





function managestatechange()
{
switch (requester.readyState)
{

case 2, 3:
//document.getElementById("loading_label").style.display = "block";
//document.getElementById("loading_label").innerHTML = "Loading...";
break;

case 4:
//document.getElementById("loading_label").style.display = "none";
//alert(requester.responseText);
if (requester.status == 200)
{
if (trim(requester.responseText) == "TRUE")
{
//alert("the part no " + part + "exists.Save Data!!!");
//return_value = true;
process_save(1);
}
else
{
//alert("the part no " + part + " doesn't exists.");
//return_value = false;
process_save(0);
}
}
else
{
return_value = false;
}
break;
}
}

Earth & Sky : Transcript - Power Naps: "DB: This is Earth and Sky. A listener writes, 'I was talking to my teacher about 'power naps' and he said that if you sleep for longer than 20 minutes and less than 40 minutes, you get a lot of energy.'

JB: Your teacher's advice is right on. No matter how long you sleep at night, your body's programmed to get sleepy in the early afternoon. A short nap can give you alertness and energy. Studies suggest that a 30-minute nap is usually more restorative than a nap of, say, two to three hours.

DB: That's partly because with a long nap, your sleep can progress into deeper slow-wave sleep, which contributes to 'sleep inertia' -- that grogginess you feel for a while after waking up. Even a short nap can produce some sleep inertia, but it doesn't last long. You can overcome it by increasing metabolic activity in your body and brain -- that is, get up, move around, splash water on your face.

JB: In the early '90s, NASA researchers studied airline pilots on long transpacific flights. They allowed one of three pilots to take up to a 40-minute nap during non-critical times in the flight. The pilots who were allowed to rest were more alert and performed better during descent and landing than the unrested pilots. These so-called 'power naps' can help anyone boost their brain function. That's especially true for healthy people who aren't getting enough sleep. But even though they're great energizers -- naps can't substitute for longer periods of healthy sleep.

JB: That's our show. We're Block and Byrd for Earth and Sky."

Sunday, August 28, 2005

YEHEY!Entertainment - Never a dull moment: "This EP could either be Marcus’ idea of making practical jokes or his twisted bid to become Department of Tourism endorsers. Check out the lyrics of “Wow Kalabaw” – “At habang papalayo sa Ermita’y gumagaan ang mundo/at habang papalayo sa Manila’y bumabait ang tao/o ikaw nang magsabi kung ito nga ay totoo/ba’t di mo subukang mamasyal sa bayan mo.” "

Saturday, August 27, 2005

float data type are not for monetary calculation. use decimal

set nocount on

select totF = 10.21 - 10.2, totD = convert(float, 10.21) - 10.2

declare @t table
(
f float,
d decimal(10,2)
)


declare @i integer
set @i = 0
while @i < 10
insert into @t(f,d) select 0.1, 0.1
set @i = @i + 1
end

select sumF = sum(f), sumD = sum(d) from @t

set nocount off

--------------------------------------------

totF
.01
totD 1.0000000000001563E-2


sumF
0.99999999999999989
sumD 1.00

Trading Wisdom-The Wolverine Way: "The Wolverine Way

Trading Wisdom

May 8, 2005


I have lost track of the number of times I have told traders to 'MAKE YOURSELF STRONG.'

There are five aspects to making yourself strong: physical, mental, emotional, spiritual and technical. I will have a lot to say about each of each in future Trading Wisdoms. But, I thought today you might like to know which animal possess the best qualities to be a successful trader. The more I thought about it, the more I realized that it is the Wolverine. Yes, the wolverine!"

Small game mounts by Fraser's Taxidermy Studio

Can a pitbull dog kill a wolverine of the size weight? - Q&A: "They say there is no such thing as a stupid question. I disagree. "

Gates: PC will replace TV, TV will become a giant Google | The Register: "An intelligent man with a zero boredom threshold, it's no wonder he finds traditional broadcasting tedious and dull. As Gates tells the Hollywood Reporter, he hates linear assumptions."

Google - the new Microsoft? | The Register: "Trust is a precious commodity and almost impossible to regain once lost. Google's instinctive reactions to several controversies to date have been marked by naïvety and evasiveness. It often gives the impression that it's blissfully unaware of the responsibilities it carries. And while the company no longer responds to controvery by dispatching pictures of its goofy founders riding around on colored beach balls or tooling about on their Segways, it hasn't worked out a more mature approach, either. This deficiency is exemplified by company's most famous hostage to fortune - its corporate mission statement, 'Do No Evil'."

Updating columns in PostgreSQL tables effectively:


2. Changing a column from NULL to NOT NULL (or vice versa)

This is much easier -- there's a field in the system catalog we can
switch.

To change the email field to NOT NULL :

UPDATE pg_attribute SET attnotnull = TRUE
WHERE attname = 'email'
AND attrelid = ( SELECT oid FROM pg_class WHERE relname = 'pers') ;

(set the same field to FALSE to clear the NOT NULL setting.)

This change does *not* require any fixing of indexes, triggers, etc. The
only problem is when you change a column to NOT NULL, and there are null values in it. In this case, PostgreSQL will *allow* the initial change, but refuses any UPDATEs to records with NULL values in the field. If you do set it to NOT NULL when there are NULL values present, the only sane choice would be to immediate populate those NULL values.


3. Adding a Primary Key

A primary key in PostgreSQL is a unique index on a column which is NOT NULL. Unless you name the primary key differently, PostgreSQL assumes the name of the key is '_pkey'.

Creating a primary key is easy:

CREATE UNIQUE INDEX pers_pkey ON pers ( id );


Thursday, August 25, 2005

PHP Editor Review - Postgres Manual -> Plpgsql-trigger:

CREATE TABLE emp (
empname text,
salary integer,
last_date timestamp,
last_user text
);

CREATE FUNCTION emp_stamp () RETURNS TRIGGER AS '
BEGIN
-- Check that empname and salary are given
IF NEW.empname ISNULL THEN
RAISE EXCEPTION ''empname cannot be NULL value'';
END IF;
IF NEW.salary ISNULL THEN
RAISE EXCEPTION ''% cannot have NULL salary'', NEW.empname;
END IF;

-- Who works for us when she must pay for?
IF NEW.salary < 0 THEN
RAISE EXCEPTION ''% cannot have a negative salary'', NEW.empname;
END IF;

-- Remember who changed the payroll when
NEW.last_date := ''now'';
NEW.last_user := current_user;
RETURN NEW;
END;
' LANGUAGE 'plpgsql';

CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp
FOR EACH ROW EXECUTE PROCEDURE emp_stamp();

Slashdot | Google, Skype and the Future of IM

Slashdot | Google, Skype and the Future of IM: "Well until Google gives me a reason not to trust them, I will. They actively compete on their merits, not on monopoly or force. If you search for an address they still give you links for Google Maps, Yahoo Maps, and Mapquest. They have donated large sums of money to OSS and have paid for many developers to work on it over them summer. Now they are using their weight to standardize instant messaging the way e-mail is standardized. If you read Google Talk's site, you'll see that a big initiative is getting instant messaging into a state like e-mail is where you can IM anyone on any network from any IM client. Jabber has server2server capabilities and thus will greatly help this effort. If I ever sense that they are misusing my information, then I'll think about leaving them, but until then, they have my full support. They have literally made the internet a better place to be.
Regards,
Steve"

Wednesday, August 24, 2005

Slashdot | Google Instant Messenger Coming Really (or Not?): "MSN has:
- reliability issues where it will go down for whole days or mornings at times- happening maybe every couple months for year. Google could use their high-availability knowledge to keep this lifeline alive
- integration to PSTN. If Google IM is always open, it's an easy transition to call family all around the world cheaply without the need to switch home phones and get a separate service (Skype for example).
- Fewer ads. Google would make its money on PSTN services, video conferences, features like '3-way calling' and 'conference calling' that need the network to merge several streams together or manage them. Google could make the ads smaller and less intrusive
- Fewer full-screen emoti-blips *hehe*
- file sharing, music sharing, resource sharing.

There is tons of untapped potential that M$ isn't doing. M$ is instead adding in full-screen emiti-blips (if I wanted a program to take over my whole screen when I'm working on something else, I would run a game.. It's happened before... typing in my credit card number and a MSN window takes focus... good thing I don't look at the keyboard when I type).

IM isn't just IM anymore. IM is about communication, information sharing, etc. All of Google's services are INFORMATION (search, maps, etc) or COMMUNICATION (gmail, talk) based- they're just adding more to the mix."

Private Declare Function InternetGetConnectedStateEx Lib "wininet.dll" Alias _
"InternetGetConnectedStateExA" (lpdwFlags As Long , lpszConnectionName As Long , _
dwNameLen As Long , ByVal dwReserved As Long ) As Long

Function IsConnected() As Boolean
Dim lNameLen As Long
Dim lRetVal As Long
Dim lConnectionFlags As Long
Dim LPTR As Long
Dim lNameLenPtr As Long
Dim sConnectionName As String
sConnectionName = Space$(256)
lNameLen = 256
LPTR = StrPtr(sConnectionName)
lNameLenPtr = VarPtr(lNameLen)
lRetVal = InternetGetConnectedStateEx(lConnectionFlags, ByVal LPTR, ByVal lNameLen, 0&)
IsConnected = (lRetVal <> 0)
End Function

'also, info is in the registry
HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Services \ RemoteAccess \ Remote Connection Is non zero.

Tuesday, August 23, 2005

The Bereans: Apologetics Research Ministry

mySQL to PosgreSQL

Th Topic: searching and sorting

Sunday, August 21, 2005

Rich Internet Application

: "From a business point of view, applications will soon become a utility just like electricity. They'll be offered on a pay-as-you-go basis, with RiA basically installed on demand, and disposable like a box of tissues."

Serials & keys - unlocks the world

serial nos.

vb techniques:

01 Overview
02 Sample code
03 IDE
04 Syntax
05 Data types / variables
06 Operators
07 Boolean logic
08 Strings
09 Arrays
10 Conditional flow
11 Scope
12 Functions / subroutines
13 Files / Folders
14 System functions
15 Graphics
16 Sound
17 Date-Time
18 Math
19 Printing
20 Error handling
21 Controls
22 Objects
23 Databases
24 SQL
25 Limitations
26 Summary of functions
27 Windows API
28 ASCII Table
29 Collections
30 Subclassing
31 Distribution
32 Top 100

applications

Associate an extension with the app
Check regional settings
Close a second app with SENDKEYS
Create a shortcut to your app in any folder
Create desktop shortcut
Dialog - color - using API
Dialog - file - using API
Dialog - folder - using APi
Dialog - font - using API
Find default application for a file
Find prior instance of EXE
Get list of available fonts
Limit Size of Window
MRU for menus
Open Help file
Popup menu
Put app icon in system tray
Put app in Explorer context menu
Put app in SendTo menu
Show/hide mouse cursor
Simulate a mouse click
Start new application and wait for it to finish
Startup with Windows (use wshom)
Stop flickering
Test if application is running within IDE
Toggle menu checkmark

arrays

Convert an array to lower case
Cycle through an array
Deal a deck of cards
Erase an array
Randomly shuffle an array
Remove element from array by content
Remove element from array by position
Search an array
Write an entire array into a file #1
Write an entire array into a file #2

clipboard

Copy image to clipboard
Copy selection to clipboard
Copy text to clipboard

controls

All - automatically highlight content on focus
All - capture any key
All - force lower case as keys are entered
All - use Enter key to move to next control in TAB sequence
Checkbox - set with Boolean value
ComboBox - change width of drop down part
ComboBox - create MRU for dropdown list
ComboBox - remove multiple selected items
Common dialog - multiple files from common dialog
Common dialog - SaveAs code
File System Controls - how to synchronize
Imagelist - add images at run time
Listbox - use API for fast search
Listbox - use API to select all
ListView - autosize column widths
Optionbutton - determine which is selected
Picturebox - remove image
Richtextbox - find and replace
Richtextbox - first visible line/position of 1st char on the line
Richtextbox - merge contents of two richtextboxes
Richtextbox - prevent flicker of richtextbox during reposition
Richtextbox - word wrap
Textbox - automatically highlight content
Textbox - select all text on focus
Textbox - undo (API)
Textbox - use Enter as TAB
Timer - extend control to large intervals
Toolbar - responding to button selection
Toolbar - responding to menu selection
TreeView - set background color
TreeView - traverse the tree

date-time

Time - elapsed time between 2 dates
Timer - milliseconds between 2 events

files binary

Determine if file is binary
Display only text conten of binary file
Open file with default Windows application
Read/write data to a specific location within the file
Read/write entire file at once
View in hex format

files text

Open text file with default text app
Open text file with Notepad
Read text file all at one time
Read text file into a string
Read text file into an array #1
Read text file into an array #2
Read text file one character at a time
Read text file one line at a time
Remove a character from a text file
Save array to file (fast)
View text file content
Wordwrap

files

Backup and Restore a file
Create full pathname
Delete file to recycle bin
Extract file name from full path
File exists
File properties (size/date/attributes)
FileSave
Get unique temporary file name
Is path a folder or file
Merge path and filename to get valid full path name
Move a file
Rename file list
Select File (dialog window)

flow control

Cycle through all controls on a form
Cycle thru 1 to n in a loop
Repeat code every N cycles
Use select case to evaluate multiple expressions

folders

Create a full folder path
Delete a folder and its subfolders
Drive exists
Folder exists
Get folder attributes
Get list of drive letters
Get type of drive
Open DOS window at folder
Open Window at folder
Open Windows Explorer at folder
Select folder (dialog window)

fonts

List all fonts

forms

Capture Enter key
Center a form
Create elliptical form
Disable form Close button
Keep form on top
Make a form cover the entire screen
Minimize all forms
Move form without using title bart
Put bitmaps in menus
Remove the border from a window
Set min/max size of form
Splitter, horizontal (form-based)
Splitter, horizontal (splitter bar)
Unload all forms
Unload event code

free controls and tools (non-commercial use)

Free programming tools

graphics

Convert between Long, RGB, VB, and Web colors
Draw text with a shadow
Get JPG/GIF/BMP/PNG image size
Get random color
Get screen resolution
Gradient - apply to a picturebox, 2 colors, 4 directions
Gradient - apply to form, 2 colors, 4 directions
Gradient - full spectrum
Non-centered wallpaper
Overlay an image
Read/write/display/convert GIF/JPG/BMP
Resize an image, keeping aspect ratio
Screen capture
Set wallpaper

internet

Check for Internet connection
Create URL shortcut
Create web page (HTML) from code
Download file from the web using API
Download web page (capture as string)
Get remote file information - size, date
Get stock prices
Open a web page in default browser
Send email using default app
Upload file (Freeware EZ-FTP)
Upload file (Internet Transfer Control)

math

Boolean comparison
Check for not null
Random integer within range
Round down
Round to 2 decimals
Round to n decimals
Round up
Swap two variables
Test for even
Test for non-zero
Test two variables for zero
Toggle between 0 and -1
Toggle between 0 and 1
Toggle between 1 and 2

misc-commands

Dial a Phone Number #1
Dial a Phone Number #2
Run code one time only within a subroutine
Show Onscreen Keyboard

multimedia

Play CD (MM control)
Play sound (API only)
Play sound (MM control)
Play video (MM control)
Record sound (MM control)

navigation

Find a single file - imageshlp.dll
List files and folders - API (pattern)
List files and folders - Dir$ (pattern)
List files and folders - FSO
List files and folders - SysFileControls

printing

Color printing
Print form image
Print images, positioned and scaled
Print preview
Print text, positioined, justified and size

registry

Clear application settings from registry
Edit registry key
Use registry to save program settings
Write registry value, any location using API

security

Checksum
Encrypt a file (no password)
Encrypt a file (uses password)
Encrypt a string (no password)
Encrypt a string (uses password)

sort

Bubble sort
Bubble sort (improved)
QuickSort
Using SHELL to DOS

strings

Compare leftmost character
Convert Byte array to string
Count occurences of string
Delete carriage returns from textbox
Eliminate duplicate character pairs in a string
Find text before/between/after two target strings
Find/replace
Get first word in a string
Split string into array
Using format$

system

Disable Ctrl-Alt-Del
Get computer name
Get handle of window from caption title
Get name of special folders
Get user name
Get Windows and System directories
Get Windows version
Hide the Window's taskbar
Hide/show taskbar or desktop
Open/close CD door
Reboot, restart or logoff system
Reboot, restart or logoff system (XP only)
Serial number of drive
Set environmental variables

Saturday, August 20, 2005

crystal report. suppress last page alternative

instead of New Page After
and Suppress if OnLastRecord

put this in the formula of NewPageAfter

RecordNumber < COUNT({ado.RecId})

no more need for Suppres if OnLastRecord

Crystal Enterprise and Crystal Reports consulting and training from The ABLAZE Group, Inc.: "...how to size bitmaps without 'stretching' them out of proportion
You can actually format a bitmap image using the Format Editor. Right click on the bitmap, select Format Graphic, click the Picture tab. On the Picture tab type in the same percentages for width and height. Click OK. The image will have a perfect 'aspect ratio' (the relationship between height and width). "

Friday, August 19, 2005

wrong averagecost

cdosys

cdosys


cdosys



Dim ObjSendMail
Dim iConf
Dim Flds

Set ObjSendMail = Server.CreateObject("CDO.Message")
Set iConf = CreateObject("CDO.Configuration")
Set Flds = iConf.Fields

Flds("http://schemas.microsoft.com/cdo/configuration/sendusing") = 1

'**** Path below may need to be changed if it is not correct
Flds("http://schemas.microsoft.com/cdo/configuration/smtpserverpickupdirectory") = "c:\inetpub\mailroot\pickup"
Flds.Update

Set ObjSendMail.Configuration = iConf
ObjSendMail.To = "someone@someone.net"
ObjSendMail.Subject = "this is the subject"
ObjSendMail.From = "someone@someone.net"

' we are sending a text email.. simply switch the comments around to send an html email instead
'ObjSendMail.HTMLBody = "this is the body"
ObjSendMail.TextBody = "this is the body"

ObjSendMail.Send

Set ObjSendMail = Nothing

Method 2 ( Using mail forwarding on port 25 )
Include this metatype library code on the page you use this emailing with code because there are some things in it this method needs. You can probably get rid of these two lines if you figure out what it references but I didn't take the time to look.






Dim ObjSendMail
Dim iConf
Dim Flds

Set ObjSendMail = Server.CreateObject("CDO.Message")
Set iConf = Server.CreateObject("CDO.Configuration")

Set Flds = iConf.Fields
With Flds
.Item(cdoSendUsingMethod) = 2
.Item(cdoSMTPServer) = "mail-fwd"
.Item(cdoSMTPServerPort) = 25
.Item(cdoSMTPconnectiontimeout) = 10
.Update
End With

Set ObjSendMail.Configuration = iConf

Set ObjSendMail.Configuration = iConf
ObjSendMail.To = "someone@someone.net"
ObjSendMail.Subject = "this is the subject"
ObjSendMail.From = "someone@someone.net"

' we are sending a text email.. simply switch the comments around to send an html email instead
'ObjSendMail.HTMLBody = "this is the body"
ObjSendMail.TextBody = "this is the body"

ObjSendMail.Send

Set ObjSendMail = Nothing
Set iConf = Nothing
Set Flds = Nothing


Method 3 ( Using remote mail server )


Dim ObjSendMail
Set ObjSendMail = CreateObject("CDO.Message")

'This section provides the configuration information for the remote SMTP server.

ObjSendMail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2 'Send the message using the network (SMTP over the network).
ObjSendMail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") ="mail.yoursite.com"
ObjSendMail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
ObjSendMail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = False 'Use SSL for the connection (True or False)
ObjSendMail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 60

' If your server requires outgoing authentication uncomment the lines bleow and use a valid email address and password.
'ObjSendMail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1 'basic (clear-text) authentication
'ObjSendMail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusername") ="somemail@yourserver.com"
'ObjSendMail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendpassword") ="yourpassword"

ObjSendMail.Configuration.Fields.Update

'End remote SMTP server configuration section==

ObjSendMail.To = "someone@someone.net"
ObjSendMail.Subject = "this is the subject"
ObjSendMail.From = "someone@someone.net"

' we are sending a text email.. simply switch the comments around to send an html email instead
'ObjSendMail.HTMLBody = "this is the body"
ObjSendMail.TextBody = "this is the body"

ObjSendMail.Send

Set ObjSendMail = Nothing

In addition to what you see here there are plenty of properties you can add to these examples.
Here are a few examples.

Carbon Copy
ObjSendMail.CC = "someone@someone.net"

Blind Carbon Copy
ObjSendMail.BCC = "someone@someone.net"

Send Attachment (we hard code it here, but you could specify the file path using Server.Mappath as well)
ObjSendMail
.AddAttachment "c:\myweb\somefile.jpg"

Thursday, August 18, 2005

where is the bug?

coding at 2am

(CASE WHEN sc.IsNullable = 1 THEN ',,adFldIsNullable' + ELSE '' END)

wake up 7am

spotted that nasty bug the "+" sign is left when i copy-paste the string

(CASE WHEN sc.IsNullable = 1 THEN ',,adFldIsNullable' ELSE '' END)

poor mental capacity when sobra na inaantok :)

Wednesday, August 17, 2005

Science News Article | Reuters.com: "SYDNEY (Reuters) - Scientists in Australia's tropical north are collecting blood from crocodiles in the hope of developing a powerful antibiotic for humans, after tests showed that the reptile's immune system kills the HIV virus.

The crocodile's immune system is much more powerful than that of humans, preventing life-threatening infections after savage territorial fights which often leave the animals with gaping wounds and missing limbs.

'They tear limbs off each other and despite the fact that they live in this environment with all these microbes, they heal up very rapidly and normally almost always without infection,' said U.S. scientist Mark Merchant, who has been taking crocodile blood samples in the Northern Territory.

Initial studies of the crocodile immune system in 1998 found that several proteins (antibodies) in the reptile's blood killed bacteria that were resistant to penicillin, such as Staphylococcus aureus or golden staph, Australian scientist Adam Britton told Reuters on Tuesday. It was also a more powerful killer of the HIV virus than the human immune system.

'If you take a test tube of HIV and add crocodile serum it will have a greater effect than human serum. It can kill a much greater number of HIV viral organisms,' Britton said from Darwin's Crocodylus Park, a tourism park and research center."

NBC12 Online | Mob scene, several hurt in rush for cheap laptops: "Mob scene, several hurt in rush for cheap laptops

From NBC12 News
Tuesday, August 16, 2005

See Video

What started as a sale turned into a mob scene as thousands of people pushed their way through the Richmond International Raceway gates to buy a $50 iBook laptop computer from Henrico County Schools Tuesday morning."

PHP, Perl and Python on the wane? | The Register: "Gerin added that if PHP was losing support then Zend's business would have fallen by at least 20 per cent in line with EDC's figures. 'That hasn't happened. Quite the contrary,' Gerin said.

EDC blamed the drop on a failure for PHP, along with Perl and Python, to penetrate the enterprise space. An EDC spokesman predicted that the decline could be halted and reversed with this year's work between Zend and its new backers.

'This appears to be a long-term shift - there's a pretty steady growth in developers who don't intend to use it [PHP]. We may see this trend start to reverse itself in six months with SAP, Oracle and IBM pushing on it,' the spokesman said.®
Related stories"

HP's Small & Medium Business Online Store - A dream come true: "HP Compaq Tablet PC tc1100
HP Compaq Tablet PC tc1100
$1,649*
after $475 instant savings



* Intel® Centrino™ Mobile Technology
o Intel® Pentium® M Processor 1.10GHz
* Microsoft® Windows® XP Tablet PC Edition



* 256MB 1 DDR SDRAM module
* 40GB (4200 rpm) hard drive
* 10.4' XGA (1024x768)
* Price includes $475 instant savings

"

Unix Review > UnixReview.com > going, Going, GONE!: "Dept. 1127: going, Going, GONE!
by Peter H. Salus

In 1969, UNIX was created at Bell Labs.

For decades, the source of the AT&T dialect of UNIX came from the researches of workers in department 1127.

When the 'Baby Bells' split from 'Ma Bell,' department 1127 survived. When AT&T and Lucent split, 1127 survived.

But the new reorg at Bell Labs finally breaks up what's left of 1127 entirely. Theory people will go to one place, systems people to another, I'm told. I'm not sure what happens to those who fall in neither camp. There was no malice, so far as I can tell — just an administrative reorg forced by recent cutbacks and layoffs and departures that left the whole research area with too many managers and too few researchers.

Ken Thompson retired to California.
Brian Kernighan is a Professor at Princeton.
Doug McIlroy is a Professor at Dartmouth.
Rob Pike and Dave Presotto and Sean Dorward are at Google.
Tom Duff is at Pixar.
Phil Winterbottom is CTO at Entrisphere.
Gerard Holzmann is at NASA/JPL Lab for Reliable Software.
Bob Flandrena is at Morgan Stanley.

To the best of my knowledge, Dennis Ritchie and Howard Trickey remain, enisled.
A former employee at 1127 remarked:

'My take is that 1127 probably reached Schiavo status when Rob, Presotto, et al. fled west to Google.
'But it's still sad to see the final demise, both of a particular institution and as a further nail in the coffin of the sort of research environment Bell Labs once represented.'

That may be the worst effect. DEC Labs are gone. XEROX PARC transmogrified into 'Palo Alto Research Center Inc.' on 4 January 2002. It's a waning of research potential.

Ave atque vale, guys. 'And thanks for all the fish.'"

Linux.com - Introduction porting vb6 to linux

Linux.com - Introduction

legalize your software

Philippine Daily Inquirer, issued today, WARNING: you have 30 days to legalize your software. Oplan Nationwide crackdown starts september 16.

Tuesday, August 16, 2005

Body Language - diagnosing early signs of illness

Welcome

Slashdot Effect

Slashdot Effect:

"For those that have not heard of the Slashdot Effect, it occurs when your web site is mentioned on the front page of a story on slashdot.org which is very popular since it is the "news for nerds" site. Because thousands of web surfers will click on your site within an hour of it being posted, it really stresses your web server (and network connections) and often results in your web site becoming unresponsive ... or a "smoldering pile of rubble" due due to the slashdot effect. Note that any heavily trafficked site can generate lotsa inbound traffic to your web server, so technically the "slashdot effect" is a generic term referring to this phenomena of a large increase in "flash" traffic, often times resulting in a (basically) Distributed Denial of Service.

The Slashdot thundering herd has made several "visits" to my web site - in 2002 & 2003 for my christmas lights and christmas webcam and then in 2004 for my halloween decorations and halloween webcam. My ISP popped a 40-amp circuit breaker in 2002 (really did happen!), but you can read my writeups of the:

* Christmas 2003 Slashdot Effect Analysis
* Halloween 2004 Slashdot Effect Analysis
* Christmas 2004 Slashdot Effect Analysis

While numerous folks have written about the Slashdot Effect, this was a little different in that not only was it a test of "digital" stuff like the web server, ISP bandwidth, Perl/CGI code, but also "analog" stuff as the code has interfaces to various sensors and the webcam itself, plus you are turning a lotta lights ON & OFF - it certainly provided one heck of a light show for the neighbors! ;-)

Christmas/2004 Update: Now using mod_perl ... shoulda done this a long time ago - ApacheBench testing shows CGI is now capable of 20 requests/second versus 4 using cgi_exec ... so this rocks ... and even uncovered a coding boo-boo where I forgot to close a lock file in a certain case - but I'm sure there are few others that will pop-up in "stress" testing. And once I disabled KeepAlive in httpd.conf, the 2.4 GHz XEON (with a Gbyte of RAM) held up pretty darn decently to not one, but two waves of (inter)national media attention as the christmas lights webcam hoax was revealed. "

Slashdot FAQ - About Slashdot: "share your opinions, but don't expect everyone else to think the same."

Sunday, August 14, 2005

some vb6 pitfalls

Sub ChangeText(ByRef ct As String)
ct = "Michael"
End Sub

Private Sub Command3_Click()
ChangeText Text1.Text
End Sub

the above code will not change tex1.text to michael

instead you must change it to following

Sub ChangeText(ByRef ct As String)
ct = "Michael"
End Sub

Private Sub Command3_Click()
dim S as string
ChangeText s
Text1.Text = S
End Sub

passing properties to byref parameters in vb.net actually works, we don't ever need anymore a work around, but not supported in c#, seems some kind of magic though :)

Comparing C# to Java: "Posted @ 12/6/2004 6:11 PM
Of course I agree, are you crazy? Well, only very political people object to the fact that C# is better than java. Oh the library is even better. On the web asp.net is better than JSP. Where is Java better? Hmm, I would say cross-platform support, but then mono is there. But mono doesn't support winforms yet, ok, but it will within a year. But then, Swing sucks more than anything in world. So I don't see how java is better, but I wouldn't complain that we are using java in a project. Java is a good language too, but I would prefer C# for almost every project, except those which require me to run on Unix etc...
"

Comparing C# to Java: "Oh, and everyone knows that stealing Anders Hejlsberg was way more important than anything they stole from Java ; )."

I'ts life, but not as we know it... : There’s More to Java vs. .NET Than Technology: "There’s More to Java vs. .NET Than Technology

A new colleague of mine, Raynni Jourdain (LogicaCMG, Arnhem), pointed me towards this article about Java vs. .NET.

In short, it says .NET for projects that have ease-of-use, need quick time to market and a lifespan of 2-5 years and Java for more complex projects, scalability and a lifespan of 5-10 years.
I'm not a Java expert, but I think I disagree...

Why couldn't you build complex projects with .NET? I think you can...!

When it comes to .NET vs Java, the words of an classic Irving Berlin song come to mind:
“Anything you can do, I can do better
I can do any thing better than you...“"

I'ts life, but not as we know it... : There’s More to Java vs. .NET Than Technology: "Perhaps I should mention I'll be joining Avanade (www.avanade.nl) in August.

Avanade is a joint-venture of Accenture and Microsoft, so maybe, just maybe, I'm a bit biased.... ;-) "

Java vs. C#: "Basically C# is the first component oriented language in the C/C++ family"

Saturday, August 13, 2005

what?! dbf!

C:\Program Files\EA Sports\NBA LIVE 2005\database\originaldb

nba live uses dbf. how i discover this by happenstance?

this day nirecode ko s visual c++ yung ginawa ko program dati s watcom c++ na pang open ng DBF files. with a few code tweaks, the program seamlessly compiles in visual c++, maybe because i know what functions are standard across different types of c++ compilers :)

nung itetest ko na yung compiled exe ng visual c++. naghanap ako ng dbf file na pagtetestingan. marami na-search ang windows na dbf files under directory ng NBA live.

so, sa DBF files lng pala nakalagay mga player informations, game stats, teams, etc, ng NBA live :D

somehow meron pa rin soft spot sa heart ko DBF files :) it's the first file format i hacked without reading documentation and without searching internet. di pa masyado popular internet noon way back 96, no such thing as google at the time and yahoo just started their initial public offering then.

pag magprogram nga ako ng games, dbf na rin gagamitin ko to store game information :)

aaralin ko uli sabay c# and c++, meron pa rin naman pointers sa c#


tidbits:

watcom c++ comes from powersoft, the same company that create sybase sql and powerbuilder.

sybase sql used to be joint project of microsoft and sybase, they parted ways, microsoft now do their own sql server.

watcom c++ used to be the game developer's programming language of choice when there's no windows 95 and directx yet. watcom c/c++ is a very optimized compiler able to compile 32 bit DOS program using DOS 4GW protected mode


me:

time change, i like to use new and advance tools

"If the only tool in your toolbox is a hammer, you tend to treat every problem like a nail"



Benjamin Franklin defined man as "the tool-making animal." If he had added the phrase "with foresight," he would have adequately described Homo faber , man the technologist.

Inventiveness was the indispensable condition for the survival of the human species. Without fur or feathers, shell or scale, ancestral man stood naked to the elements. Without fang or claw or tusk to fight his predators, without speed to elude them, without camouflage to deceive them or the ability to take to the trees like his cousin, the ape, man was physically at a hopeless disadvantage. What he developed to deal with his deficiencies was the capacity to invent.

Man possessed not only sensory perceptions (though these were less acute than those of many of his fellow creatures), he also possessed imagination and finger-skills. He did not just improvise to meet an emergency as an ape might in using a broken branch as a weapon. He also saw the need for keeping a club handy -- he planned ahead.


Benjamin Franklin

Slashdot | Did Microsoft Invent The iPod?:


" Re:Invention.. (Score:4, Interesting)
by Jeff DeMaagd (2015) on Saturday August 13, @01:23AM (#13309854)
(http://www.demaagd.com/ | Last Journal: Sunday October 27, @07:53PM)
Edison was briliant, but yes, IIRC, he was also likely a jerk, a petty one at that.

What I heard was that he wanted to discredit alternating current (AC) power, and electrocuting animals was his way of doing it. Edison favored direct current (DC) power. The problem is that given the technology of the time, and it is still largely true today, due to the physics involved, AC is generally a better long-distance electrical power transmission method.

I'm not sure how stable Tesla was, but he was right about AC.
[ Reply to This | Parent ]

* Re:Invention.. by ThePromenader (Score:1) Saturday August 13, @02:21AM
o Re:Invention.. by ettlz (Score:2) Saturday August 13, @05:02AM
* Re:Invention.. by TapeCutter (Score:3) Saturday August 13, @02:54AM
* Physics and You by poptones (Score:3) Saturday August 13, @03:41AM
* Re:Invention.. by chthon (Score:2) Saturday August 13, @05:00AM
* 1 reply beneath your current threshold.

# What they don't teach in school about Edison by seanadams.com (Score:2) Saturday August 13, @01:29AM

Re:Invention.. (Score:4, Informative)
by TripMaster Monkey (862126) * on Saturday August 13, @01:30AM (#13309873)
(Last Journal: Tuesday May 17, @11:38AM)

Yes, Edison electrocuted many animals, but it wasn't to disprove Tesla's theories. Rather, it was to 'demonstrate' that AC electricity (Tesla's system), was more lethal than Edison's preferred DC. Edison put on elaborate shows in which he electrocuted horses, dogs, elephants, and just about any other animal he could get his hands on (he was also known for paying children 25 cents for each stray dog they could bring him). Edison claimed that while AC electricity was obviously lethal, DC was not (which is patently false).

Interesting that Edison's name is synonomous with electricity even today, although the electricity we use in our homes is Tesla's alternating current."

600 - 500 is not 100

600: legacy accounts


500: all count nung accountinstallment sa new system
200 legacy accounts migrated + 300 new accounts


-----------------------------

mathematically, difference will be 100
600 - 500 = 100

pero yung legacy import lookup, reports 400 in count

600 (legacy)
500 (new)

100 is the supposed difference

pero 400 ang nireport ng query, what could be the problem?


--------------------------

what could be the likely scenario?

since we're not dealing with plain math numbers here, it's more of a sets scenario, something like set theory or venn diagrams :) how i miss discrete mathematics subject in college, antaas ng grade ko sa subject na to.


typical inquiries like this can provide some hints or explanation about the numbers involve:

"what accounts in Sets of the New system accounts not found in the Sets of the legacy account or vice-versa?"


maaari meron mga accounts na meron sa new system na wala pa sa legacy, so baliktad.


legacy(600 total)

new(500 total) sabihin natin na yung 200 is yung nimigrate from legacy. and yung other 300, is yung new accounts na hindi pa rin na-eencode sa legacy ni rhea(n-b-backlog n rin halimbawa ang main sa encoding ng new accounts)

so yung query like this will not return 100:

SELECT account FROM legacySystem WHERE account NOT IN (SELECT account FROM newSystem)

it will return: 400(not 100)

because: yung actual lng na na-itransfer na legacy papuntang new is 200(not 500)

not quite a laptop. not quite a tablet pc. susunod talagang actual tablet na bibilhin ko

unang laptop(or desknote to be precise) ko is ecs desknote iBuddieXp. AMD Athlon XP 2000+, 512 MB mem, 20 gig hd.

di masasabing talagang laptop eto ecs, cause sobrang init di pwedeng ipatong sa lap. at external pa yung battery

pangalawang laptop ko is neo t210c(the convertible one) tablet pc, Pentium M 1.6 Dothan, 768 MB, 40 gig hd.

now i got a real laptop, pero seems not a real tablet pc. walang digitizer, yung touch screen lng bale. ang difference ng digitizer pen against sa plain pen is yung sampling rate ng input ng digitizer is around 100 to 150. unlike ng pen na emulated by mouse driver lng, it's around 30 lng. so mas responsive ang digitizer, mas fine yung strokes.

mag-u-upgrade din ako sa actual tablet pc. around year 2007 pag mura na yung pentium m sonoma and common na yung windows vista, mas marami na siguro improvements sa tablet pc. maganda siguro tablet slate, para talagang magaan, preferably electrovaya next na purchase ko, 6 hours something battery life

Slashdot | The NetBSD Toaster: "In fact, that's how it works. Insert bread, start webserver, advertize its existence on Slashdot. Resulting meltdown turns bread into toast."

Google Community: Integrated Google Messenger: "If Google absolutely provides GMAIL, it would conquer YahooMail in one day.

If Google releases Google Messenger, it would kill those all, except Pirch or mIRC.

Like Google Search kills them all, including Yahoo Directory.

Yahoo! vs GOOGLE
Where do people go on yahoo.com?

mail.yahoo.com~ 39%
search.yahoo.com~ 9%
news.yahoo.com~ 5%
login.yahoo.com~ 4%
yahoo.com~ 3%
auctions.yahoo.com~ 2%
bid.yahoo.com~ 2%
finance.yahoo.com~ 2%
sports.yahoo.com~ 1%
kids.yahoo.com~ 1%
club.yahoo.com~ 1%
profiles.yahoo.com~ 1%
groups.yahoo.com~ 1%
store.yahoo.com~ 1%
personals.yahoo.com~ 1%
my.yahoo.com~ 1%
photos.yahoo.com~ 1%
launch.yahoo.com~ 1%
games.yahoo.com~ 1%
fantasysports.yahoo.com~ 1%
messages.yahoo.com~ 1%
wrs.yahoo.com~ 1%
music.yahoo.com~ 1%
stock.yahoo.com~ 1%
hk.yahoo.com~ 1%
dir.yahoo.com~ 1%
movies.yahoo.com~ 1%
rd.yahoo.com~ 1%
edit.yahoo.com~ 1%
Other websites~ 13%

[ http://www.alexa.com/data/details/traffic_details?q=&url=yahoo.com ]

Where do people go on google.com?
google.com~ 80%
images.google.com~ 8%
gmail.google.com~ 6%
news.google.com~ 2%
groups-beta.google.com~ 1%
froogle.google.com~ 1%
Other websites~ 2% "

Developing Applications Using Your Tablet PC: "A: There are actually quite a few differences. Tablet PC ink is collected from an electromagnetic digitizer that samples at 130 times/second, and has a resolution 7-10 higher than a screen resolution. Pocket PC's, on the other hand, use a resistive touch screen, sample at about 30 times/second, and have the same resolution as the screen. The ink on a tablet is also rendered using Bezier smoothing and anti-aliasing, so it looks much better than the ink on a Pocket PC, which is very pixelated by comparison. With that said, inking UI's can translate well because both devices are pen driven---but the ink API's are different and the ink itself does not translate well between the two."

Friday, August 12, 2005

vbCity/DevCity.NET Forums :: Visual Basic :: VB & Databases :: FAQ :: How to Read/Write Image files from/to Access DB using ADO:

This sample demonstrates how to use ADO object model to read/write Image files from/to an Access Database. ADO object model provides great capability to developers. Using ADO it is possible to access Data from any kind of Data source. That's why Microsoft uses the Term "Universal Data Access". Basically in this sample we will be using the 2 methods exposed by ADO Recordset object called AppendChunk and GetChuck.

AppendChunk appends data to a large text or binary data Field, or to a Parameter object and it follows the syntax

Code:
object.AppendChunk Data

Use the AppendChunk method on a Field or Parameter object to fill it with long binary or character data. You can use the AppendChunk method to manipulate long values in portions rather than in their entirety. The first AppendChunk call on a Field object writes data to the field, overwriting any existing data. Subsequent AppendChunk calls add to existing data.

Note: Only the important code sections are highlighted here. Pls refer the attched code sample for complete code listing.

In this eg. we use Common dialog control to open an Image file. It can be either bmp,co,gif, or jpg.

Code:
CommonDialog1.Filter = "(*.bmp;*.ico;*.gif;*.jpg)/*.bmp;*.ico;*.gif;*.jpg"
CommonDialog1.ShowOpen
PictBmp = CommonDialog1.FileName

then based on the file, we use the file Access method (Binary Read operation) on the PictBmp to read (converts the file
to binary data)

Code:
SourceFile = FreeFile
Open PictBmp For Binary Access Read As SourceFile

then we use the Appendchunk Method of the ADO Recordset object to append the value in the byte array to the field Pict in the EMP table

Code:
Get SourceFile, , ByteData() 'Reads data from an open disk file into ByteData()
Rs(1).AppendChunk ByteData() 'Appends the left over data first

Once all the Data is append to the database call the Update method of the ADO recordset to save the changes to the DB and finall close the file handle

Code:
Rs.Update 'Commit the new data.
Close SourceFile

Reading the Image Data from the DB

In order to read the image data, we follow the exact opposite of the write method. wht basically we do here is read the binary data from
the Database and write the binary data to a disk file using the binary write method.

Code:
DiskFile = App.Path & "\image1.bmp"

If Len(Dir$(DiskFile)) > 0 Then
Kill DiskFile
End If

DestFileNum = FreeFile
Open DiskFile For Binary As DestFileNum

But inorder to get the binary data from the DB, we use the GetChunk method of the ADO Recordset object. the binary data is then transfered to the disk file using the Put method.

Code:
ByteData() = Rs(1).GetChunk(LeftOver)
Put DestFileNum, , ByteData() 'write data from a variable to disk file

Once the data is written to the disk file which is of the type image,close the filehandle and load the image file into a picture box or image control using the LoadPicture Method.

Code:
Close DestFileNum

Image1.Visible = True
Image1.Picture = LoadPicture(App.Path & "\image1.bmp")

Tech Info - W3C DOM-2 removeChild Method: "Removes the specified thing (an element/node/object) from the referenced node.
Syntax

oldthing = node.removeChild(thing)
Related Stuff

appendChild method
Parameters
Name Description Notes
node the node to be removed
Examples

// get a reference to an existing object
obj = document.getElementById('one');
// empty this object of its children
nodelist = obj.childNodes;
// now loop and remove them all
c = nodelist.length; // needed because changes dynamically
for(i = 0; i < c; i++)
{
this_node = nodelist[0]; // reference changes dynamically
removed_node = obj.removeChild(this_node);
}
// alternate method
while(obj.hasChildNodes() == true)
{
obj.removeChild(obj.childNodes[0]);
}
}

The code fragment above shows two versions of a loop which empties a node of all its child nodes."

How to Read/Write Image files from/to Access DB using ADO

Thursday, August 11, 2005

Is my brain analog or digital? | The Register: "All right, let's end this moronic debate over analog vs digital right now: The world is NOT analog. It is digital. Ask any quantum physicist if there is anything in this universe that cannot be reduced to a collection of specific quantum particles. To better illustrate this point, let us turn to that champion of analog examples, the magnetic tape. This is always put forth as the 'analog' data storage system. But what is magnetic tape? It is a ribbon of material along which magnetic _particles_ are arranged to store data. Can you store data on this tape that is represented by 1/2 a particle? No, the 'analog' magnetic tape is actually digital, its 'digit' being the magnetic particle. So-called analog systems are actually digital systems whose intrinsic level of precision is beyond that which we can (or wish to) control or observe. That does not make them 'not digital', it makes us 'not capable'.

Steven Knox"

Google: "Progress isn't made by early risers. It's made by lazy men trying to find easier ways to do something."

Wednesday, August 10, 2005

Swing and SWT: A Tale of Two Java GUI Libraries

Peter's Gekko : May 2005 - Posts

Peter's Gekko : May 2005 - Posts:
C++ for .NET at dotned

Yesterday we had the VS 2005 C++ team at the dotned user group meeting. It was a good meeting and a good talk. Ronald Laeremans is somebody who can, and will, talk for hours. The C++ vision on .net is quite interesting, let me reproduce some of the things I learned.

To me the C++ language has always been one you had to learn to live with. Never did any real C++ programming but I had to read C++ on a daily basis. All code samples were in C++, incorporating the ideas in my Delphi win32 required translating. These days I do mainly C#, a language whose syntax is far closer to C++ than Object Pascal but whose “architecture” (events, properties, components) comes far closer to Delphi.

C++ is still a major language at MS, according to the VC team 95% of the MS products is coded in C ++. The team was clearly jealous on the new star C# but gave some good reasons to use (unmanaged) C++:

* Existing code base. You can’t dump 20 years of Windows and Office development
* Backward compatibilty.
* Do your own memory management. Some code has to keep running with 0% memory free. In managed code the smallest things, like boxing an integer, can result in a memory allocation (by the CLR)
* Directly invoking an unmanaged function is checked at compile time. A dllimport in managed code is checked at runtime.

The upcoming C++ does a couple of things to bring the world of unmanaged C++ and managed code together

* To the compiler IL is just another platform target, there’s x86, Itanium and IL
* When declaring a class in C++ you can prefix the class with the value or ref keyword. The class (type) will than be compiled into a managed class which can be reused by any .net language using the assemby. A class without a prefix is a native class.
* The clr:safe compiler directive checks your code on the absence of pointers and native classes. When both criteria are met you have a built a managed assembly with C++.
* A nice feature are trivial properties and events. Declared as a property but you don’t have to write out the (trivial) getter and setter routines.

Some nice scenarios of mixed code

* Wrap up DirectX complexities. Directly address DirectX objects iterated in a .net foreach loop.
* Give an MFC app a .NET Winforms UI. As a demonstration the team had built a customized slide sorter for Powerpoint. Powerpoint in an MFC app and Winforms is very good in building a sophisticated UI.

C++ is clearly not intended as a mainstream language. You can still do horrific things. And in your app you’re dealing with three kinds of memory: the stack, the managed heap and the native heap. Not for the faint of heart. I will stick to my beloved C# but have seen good things to further expand my horizon. (But will not forget pInvoke.net)

Another part of a meeting is the social networking part. Of course Sander and Hassan were there and I promissed to restore the broken links to their perfomaces on a former meeting. Is done. See you at the next meeting.

Tuesday, August 09, 2005

SQL Server Query Execution Plan Analysis: "First of all, let's look at JOIN types. SQL Server can JOIN a table using three different techniques: nested loop, hash, and merge. Generally, the fastest type of join in a nested loop, but if that is not feasible, then a hash JOIN or merge JOIN is used (as appropriate), both of which tend to be slower than the nested JOIN."

SQL Server Query Execution Plan Analysis:


If you see any of the following in an execution plan, you should consider them warning signs and investigate them for potential performance problems. Each of them are less than ideal from a performance perspective.

* Index or table scans: May indicate a need for better or additional indexes.

* Bookmark Lookups: Consider changing the current clustered index, consider using a covering index, limit the number of columns in the SELECT statement.

* Filter: Remove any functions in the WHERE clause, don't include Views in your Transact-SQL code, may need additional indexes.

* Sort: Does the data really need to be sorted? Can an index be used to avoid sorting? Can sorting be done at the client more efficiently?

It is not always possible to avoid these, but the more you can avoid them, the faster your performance will be. [7.0, 2000] Updated 8-5-2005

*****

If you have a stored procedure, or other batch Transact-SQL code that uses temp tables, you cannot use the "Display Estimated Execution Plan" option in the Query Analyzer to evaluate it. Instead, you must actually run the stored procedure or batch code. This is because when a query is run using the "Display Estimated Execution Plan" option, it is not really run, and temp tables are not created. Since they are not created, any references to them in the code will fail, which prevents an estimated execution plan from being created.

On the other hand, if you use a table variable (available in SQL Server 2000) instead of a temp table, you can use the "Display Estimated Execution Plan" option [7.0, 2000] Updated 8-5-2005

*****

If you have a very complex query you are analyzing in Query Analyzer as a graphical query execution plan, the resulting plan can be very difficult to view and analyze. You may find it easier to break down the query into its logical components, analyzing each component separately. [7.0, 2000] Updated 8-5-2005

*****

The results of a graphical query execution plan are not always easy to read and interpret. Keep the following in mind when viewing a graphical execution plan:

* In very complex query plans, the plan is divided into many parts, with each part, listed one on top of the other on the screen. Each part represents a separate process or step that the query optimizer had (has) to perform in order to get to the final results.

* Each of the execution plan steps is often broken down into smaller sub-steps. Unfortunately, you don't view the sub-steps from left to right, but from right to left. This means you must scroll to the far right of the graphical query plan to see where each step starts.

* Each of the sub-steps and steps is connected by an arrow, showing the path (order) taken of the query when it was executed.

* Eventually, all of the parts come together at the top left side of the screen.

* If you move your cursor above any of the steps or sub-steps, a pop-up windows is displayed, providing more detailed information about this particular step or sub-step.

* If you move your cursor over any of the arrows connecting the steps and sub-steps, you see a pop-up window showing how many records are being moved from one step or sub-step to another step or sub-step.

[7.0, 2000] Updated 8-5-2005

*****

The arrows that connect one icon to another in a graphical query plan have different thicknesses. The thickness of the arrow indicates the relative cost in the number of rows and row size of the data moving between each icon. The thicker the arrow, the more the relative cost is.

You can use this indicator as a quick gauge as to what is happening within the query plan of your query. You will want to pay extra attention to thick arrows in order to see how it affects the performance of your query. For example, thick lines should be at the right of the graphical execution plan, not the left. If you see them on the left, this could indicate that too many rows are being returned, and that the query execution plan is less than optimal. [7.0, 2000] Updated 12-10-2003

*****

In an execution plan, each part of it is assigned a percentage cost. This represents how much this part costs in regard to resource use, relative to the rest of the execution plan. When you analyze an execution plan, you should focus your efforts on those parts that have the largest percentage cost. This way, you focus your limited time on those areas that have the greatest potential for a return on your time investment. [7.0, 2000] Added 12-10-2003

*****

In an execution plan, you may have noticed that some parts of the plan are executed more than once. As part of your analysis of an execution plan, you should focus some of your time on any part that takes more than one execution, and see if there is any way to reduce the number of executions performed. The fewer executions that are performed, the faster the query will be executed. [7.0, 2000] Added 12-10-2003

*****

In an execution plan you will see references to I/O and CPU cost. These don't have a "real" meaning, such as representing the use of a specific amount of resources. These figures are used by the Query Optimizer to help it make the best decision. But there is one meaning you can associate with them, and that is that a smaller I/O or CPU cost uses less server resources than a higher I/O or CPU cost. [7.0, 2000] Added 12-10-2003

*****

When you examine a graphical SQL Server query execution plan, one of the more useful thing to look for is how indexes were used (if at all) by the query optimizer to retrieve data from tables from a given query. By finding out if an index was used, and how it was used, you can help determine if the current indexes are allowing the query to run as well as it possibly can.

When you place the cursor over a table name (and its icon) in a graphical execution plan, and display the pop-up window, you will see one of several messages. These messages tell you if and how an index was used to retrieve data from a table. They include:

* Table Scan: If you see this message, it means there was no clustered index on the table and that no index was used to look up the results. Literally, each row in the table being queried had to be examined. If a table is relatively small, table scans can be very fast, sometimes faster than using an index.

So the first thing you want to do, when you see that a table scan has been performed, is to see how many rows there are in the table. If there are not many, then a table scan may offer the best overall performance. But if this table is large, then a table scan will most likely take a long time to complete, and performance will suffer. In this case, you need to look into adding an appropriate index(s) to the table that the query can use.

Let's say that you have identified a query that uses a table scan, but you also discover that there is an appropriate nonclustered index, but it is not being used. What does that mean, and how come the index was not used? If the amount of data to be retrieved is large, relative to the size of the table, or if the data is not selective (which means that there are many rows with the same values in the same column), a table scan is often performed instead of an index seek because it is faster. For example, if a table has 10,000 rows, and the query returns 1,000 of them, then a table scan of a table with no clustered index will be faster than trying to use a non-clustered index. Or, if the table had 10,000 rows, and 1,000 of the rows have the same value in the same column (the column being used in the WHERE clause), a table scan is also faster than using a non-clustered index.

When you view the pop-up window when you move the cursor over a table in a graphical query plan, notice the "Estimated Row Count" number. This number is the query optimizer's best guess on how many rows will be retrieved. If a table scan was done, and this number is very high, this tells you that the table scan was done because a high number of records were returned, and that the query optimizer believed that it was faster to perform a table scan than use the available non-clustered index.

* Index Seek: When you see this, it means that the query optimizer used a non-clustered index on the table to look up the results. Performance is generally very quick, especially when few rows are returned.

* Clustered Index Seek: If you see this, this means that the query optimizer was able to use a clustered index on the table to look up the results, and performance is very quick. In fact, this is the fastest type of index lookup SQL Server can do.

* Clustered Index Scan: A clustered index scan is like a table scan, except that it is done on a table that has a clustered index. Like a regular table scan, a clustered index scan may indicate a performance problem. Generally, they occur for two different reasons. First, there may be too many rows to retrieve, relative to the total number of rows in the table. See the "Estimated Row Count" to verify this. Second, it may be due to the column queried in the WHERE clause may not be selective enough. In any event, a clustered index is generally faster than a standard table scan, as not all records in the table always have to be searched when a clustered index scan is run, unlike a standard table scan. Generally, the only thing you can do to change a clustered index scan to a clustered index seek is to rewrite the query so that it is more restrictive and fewer rows are returned.

The J2EE guy still doesn't get PHP - SitePoint PHP Blog: "Generally people talk about two types of scalability - vertical (adding new processors, disk, memory to your existing 'big box' or buy a 'bigger box') and horizontal (add extra 'boxes' and distribute load between them).

Vertical scalability is easy to implement but generally more expensive long term. There's typically a limit to how much memory, for example, you can add to your existing 'box' and the 'next box up' costs three times the price but only increases capacity by 20%.

Horizontal scalability takes more effort / cunning but can prove extremely successful, as mused in The Secret Source of Google's Power - build a 'super computer' out of dirt cheap parts. For filesystem (and by extension database) replication across multiple systems there's generally a range of mature solutions out there to choose from, many Open Source. Memory replication is another story (now go back to that important point up there)."

PHP Scales

[/] LINKMATRIX.de: LINUX 1000+ Free eLearning Tutorials

Monday, August 08, 2005

Keith Dimmock's 3 of 9 Barcode Font

vbCity/DevCity.NET Forums :: FAQ :: Visual Basic :: VB Controls & ActiveX :: General: "Creating persistable classes in VB6.0 can be tedious at best. But not anymore! Using the same object discovery techniques as VB's intellisense, this code makes persistable classes easy!

Code:
Private Sub Class_ReadProperties(PropBag As PropertyBag)
Dim ObjObject As New ObjectLister.ClsObject
Dim PropList As Collection
Dim I As Long
Set PropList = ObjObject.GetProperties(ObjObject.TypeInfoFromObject(Me))
With PropBag
For I = 1 To PropList.Count
Call ObjObject.Invoke(Me, PropList.Item(I).Name, PropList.Item(I).INVOKEKIND, .ReadProperty(PropList.Item(I).Name))
Next I
End With
Set PropList = Nothing
Set ObjObject = Nothing
End Sub

Private Sub Class_WriteProperties(PropBag As PropertyBag)
Dim ObjObject As New ObjectLister.ClsObject
Dim PropList As Collection
Dim I As Long
Set PropList = ObjObject.GetProperties(ObjObject.TypeInfoFromObject(Me))
With PropBag
For I = 1 To PropList.Count
Call .WriteProperty(PropList.Item(I).Name, ObjObject.Invoke(Me, PropList.Item(I).Name, VbGet))
Next I
End With
Set PropList = Nothing
Set ObjObject = Nothing
End Sub

The source code for the ObjectLister library is attached
The ObjectLister code was developed using a typelibrary and sample code from this site: Edanmo's VB Page"

Debunking the myth that penguins are monogomous

Catalyst: Penguin Man - ABC TV Science: "Narration:
Penguins mate for life. Well don’t they?

Not according to this man. Meet author and renowned penguin researcher, Lloyd Spencer Davis.

After 20 years studying penguins, he’s come to realise they’re dealing with many of the same relationship issues we are.

Lloyd Spencer Davis:
People always say that’ that penguins mate for life. Total bollocks.

They’re just as likely to be unfaithful, they’re just as likely to go and have a quickie, they’re just as likely to shift house and leave the kids.

Narration:
So why is being a penguin so tough on relationships?

Lloyd says it all began when the penguin made an ancient evolutionary decision.

Jonica Newby, Reporter:
“Oh look, there’s one”

Narration:
This is story about a bird who wanted to be a fish.

Narration:
We’re on the Otago peninsula in New Zealand, and Lloyd is taking me to see how the story started.

We’re looking for the penguins ancestors - who surprisingly, probably looked a lot like this.

Jonica Newby, Reporter:
They’re huge.

Lloyd Spencer Davis:
They are. This is the royal albatross. The largest flying bird in the world, absolutely amazing. And yet It’s the penguins closest relative.

Narration:
50 million years ago, the albatross-like ancestor of the penguin could see the oceans were teeming with untapped fish.

The trouble was, they couldn’t dive deeper than a few metres.

Lloyd Spencer Davis:
And that must have been so frustrating for them - their ancestors anyway, when they were looking down at all this food but they couldn't reach it, because they couldn't dive down there.

Narration:
If only they could dive deeper and stay down longer.

But that’s when they faced their first big obstacle.

You can lead a bird to water but you can’t make it sink

Jonica Newby, Reporter:
Wow, look at this.

Lloyd Spencer Davis:
Yeah it's incredible isn't it. This is an albatross skeleton. And if you are going to tak"

Who will buy Skype? Yahoo!? or Google? or Rupert Murdoch? | The Register: "In terms of rivals, Microsoft's MSN is already close to achieving a profile with its MSN Messenger which has good credibility as a telephony provider; Yahoo's instant messenger service is less credible as a voice carrier, but that will all change before the end of this year, when it unveils its plans in mobile and VoIP telephony.

In terms of technology, Skype has a real problem: it relies on 'supernodes' - users who have direct Web access to a 'real' IP address. The traffic in and out of normal nodes wouldn't be capable of travelling between two subscribers; there are no inbound routes. So the software fakes a session through a supernode.

The problem seems to be: the number of potential supernodes is dropping, and the number of ordinary nodes - behind mapped addresses or firewalls, or both - is going up rapidly.

The result: quality of calls is falling. Bandwidth available is poor compared with a year ago.

This problem is one Skype may solve before it becomes visible to potential buyers. If it thinks the solution is easy, it has no need to rush to accept a suitor.

So: if Cringeley's rumour is right, then the next two weeks will show how optimistic Skype founder Niklas Zennström is. If he sells out before September, we can deduce he's not sure about being able to solve the technical challenge. If he hangs on, we can suspect he's got it cracked."

Slashdot | March of the Penguins Tops Box Offices: "Now you know.. (Score:5, Interesting)
by Bananatree3 (872975) on Monday August 08, @03:45AM (#13267704)
(http://forums.krazyletter.com/)
The Penguins are a miraculous species, capable of extreme heroism, self-sacrifice, sorrow and unshakable love.'

Now you know why the Penguin is Linux's mascot. It is reliable, unshakable, self-sacrificing (think of all those selfless developers working night and day around the world), extreme heroism (ok, that might be taking it a little too far...)
[ Reply to This ]

Re:Now you know.. (Score:4, Funny)
by lxs (131946) on Monday August 08, @04:40AM (#13267857)
That's just typical of the Slashdot audience. How can you forget the sacrifices Windows '95 made? It died for your sins. Sometimes three times a day."

Friendster goes PHP: "Rasmus, your post is the very reason _not_ to use PHP. You're pushing session state, inter-process messaging, and application state off to a database. For Friendster's sake, I hope they have a huge clustered Oracle instance, because once they exceed the capabilities of their database, the site will fall apart.

JSP is far, far more efficient than PHP when it comes to taking load off the database, for the very reasons you mentioned above. Sandboxing every request is inherently a mistake, because to do any sort of OO would require that you load up the user's profile every single time you hit a page.

Hearing that Friendster used _Tomcat_ as their application server explains why the site was so slow. Tomcat is the reference implementation, and has never been known for its speed. I would bet that, rather than doing a costly and time-consuming conversion to PHP, had Friendster sprung for some licenses for Resin (caucho.com) the site would have performed admirably. Inter-JVM messaging in Resin is done extremely quickly, and as a JSP engine Resin is unparalleled. "

Friendster goes PHP: "Those of you asking why they switched from JSP have obviously never used Friendster, or any other JSP programmed site. They are almost always slow. I can't stand them. On the other hand, I've never been on a well-programmed PHP or Perl site that was unacceptably slow.

Of course, a lot of it is well-programmed vs. poorly programmed. But if they did a good job and implemented caching, then their new PHP site should be blazing fast for everybody. "

dBforums - Restoring database from mdf and ldf: "Have you read how many posts we have in these newsgroups that have problems attaching databases that
weren't detached first? Just because it might have worked for you doesn't mean it is supported or
that it always work!

Here is a very important quote from Books Online:

'sp_attach_db should only be executed on databases that were previously detached from the database
server using an explicit sp_detach_db operation. '

Do you still consider planning a backup strategy based on just copying the database files and hoping
that they will attach successfully a good idea?"

The 1995 SQL Reunion: People, Projects, and Politics - System R: "Mike Blasgen: There were great controversies about NULL. Just to give you an example, if you don't know somebody's age, but you know a lot of other things about them and you want to record it in a database but you don't want to put in their age. So you leave it blank, but now you sort, say, on age. Where do you want that person's age to come out: at the beginning or the end or the middle? This is NULL theology. There are the people who want to eat the egg from the big end and people who want to eat it from the little end. And then there are people who want to eat it from the middle."

vb6 middle-tier and front-end code generator

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[CodeGen_Geographic]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[CodeGen_Geographic]
GO

CREATE TABLE [dbo].[CodeGen_Geographic] (
[GeographicCode] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
) ON [PRIMARY]
GO



INSERT INTO CodeGen_Geographic(GeographicCode)
SELECT 'BranchCode'


GO


if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[CodeGen_DataTypes]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[CodeGen_DataTypes]
GO

CREATE TABLE [dbo].[CodeGen_DataTypes] (
[SqlType] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[VbType] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[VbTypeDim] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
) ON [PRIMARY]
GO





INSERT INTO CodeGen_DataTypes(SqlType, VbType, VbTypeDim)
SELECT 'bigint','DataTypeEnum.adBigInt','Long' UNION
SELECT 'binary','DataTypeEnum.adBinary','' UNION
SELECT 'bit','DataTypeEnum.adBoolean','Boolean' UNION
SELECT 'char','DataTypeEnum.adChar','String' UNION
SELECT 'datetime','DataTypeEnum.adDBTimeStamp','Date' UNION
SELECT 'decimal','DataTypeEnum.adNumeric','Variant '' Decimal' UNION
SELECT 'float','DataTypeEnum.adDouble','Double' UNION
SELECT 'image','DataTypeEnum.adLongVarBinary','' UNION
SELECT 'int','DataTypeEnum.adInteger','Long' UNION
SELECT 'money','DataTypeEnum.adCurrency','Currency' UNION
SELECT 'nchar','DataTypeEnum.adWChar','String' UNION
SELECT 'ntext','DataTypeEnum.adLongVarWChar','String' UNION
SELECT 'numeric','DataTypeEnum.adNumeric','Variant '' Numeric' UNION
SELECT 'nvarchar','DataTypeEnum.adVarWChar','String' UNION
SELECT 'real','DataTypeEnum.adSingle','Single' UNION
SELECT 'smalldatetime','DataTypeEnum.adDBTimeStamp','Date' UNION
SELECT 'smallint','DataTypeEnum.adUnsignedSmallInt','Integer' UNION
SELECT 'smallmoney','DataTypeEnum.adCurrency','' UNION
SELECT 'sql_variant','','' UNION
SELECT 'sysname','','' UNION
SELECT 'text','DataTypeEnum.adLongVarChar','String' UNION
SELECT 'timestamp','DataTypeEnum.adBinary','' UNION
SELECT 'tinyint','DataTypeEnum.adUnsignedTinyInt','Byte' UNION
SELECT 'uniqueidentifier','DataTypeEnum.adGUID','String' UNION
SELECT 'varbinary','DataTypeEnum.adVarBinary','' UNION
SELECT 'varchar','DataTypeEnum.adVarChar','String'



go

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[CodeGenFe_OneTableNoAutoId]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[CodeGenFe_OneTableNoAutoId]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[CodeGenFe_TwoTableNoAutoId]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[CodeGenFe_TwoTableNoAutoId]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[CodeGenMt_OneTableNoAutoId]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[CodeGenMt_OneTableNoAutoId]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[CodeGenMt_TwoTableNoAutoId]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[CodeGenMt_TwoTableNoAutoId]
GO

SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO












CREATE PROCEDURE CodeGenFe_OneTableNoAutoId
@TableTransactName VARCHAR(100),
@TableName VARCHAR(100)
AS

IF object_id(@TableName) IS NULL BEGIN
PRINT 'Table ' + @TableTransactName + ' does not exists'
RETURN
END





DECLARE @Tab VARCHAR(4)
SET @Tab = SPACE(4)



DECLARE @TryBlockBegin VARCHAR(8000)

SET @TryBlockBegin = @Tab + 'On Error GoTo goCatchError'
+ CHAR(13)
+ @Tab + '''Try{' + CHAR(13) + CHAR(13)

DECLARE @TryBlockEnd VARCHAR(8000)

SET @TryBlockEnd = CHAR(13) + @Tab + 'GoTo goFinally' + CHAR(13) + @Tab + '''}' + CHAR(13)


DECLARE @CatchBlockBegin VARCHAR(8000)

SET @CatchBlockBegin= @Tab + '''CatchError{' + CHAR(13) + 'goCatchError:' + CHAR(13) + CHAR(13) + char(13)

+ @Tab + 'Screen.MousePointer = vbDefault'






DECLARE @FinallyBlockBegin VARCHAR(8000)

SET @FinallyBlockBegin = @Tab + '''Finally{' + CHAR(13) + 'goFinally:' + CHAR(13) + CHAR(13)

DECLARE @FinallyBlockEnd VARCHAR(8000)

SET @FinallyBlockEnd = @Tab + '''}'




DECLARE @PkDeclare VARCHAR(8000)

set @PkDeclare = ''
select
@PkDeclare = @PkDeclare + CHAR(13) + @Tab + 'Dim ' + c.Name + ' As String'
+ CHAR(13) + @Tab + C.Name + ' = txt' + C.Name + '.Value'
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@tablename)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@tablename, i.indid, c1.colid)
and (c.name = index_col (@tablename, i.indid, 1) or
c.name = index_col (@tablename, i.indid, 2) or
c.name = index_col (@tablename, i.indid, 3) or
c.name = index_col (@tablename, i.indid, 4) or
c.name = index_col (@tablename, i.indid, 5) or
c.name = index_col (@tablename, i.indid, 6) or
c.name = index_col (@tablename, i.indid, 7) or
c.name = index_col (@tablename, i.indid, 8) or
c.name = index_col (@tablename, i.indid, 9) or
c.name = index_col (@tablename, i.indid, 10) or
c.name = index_col (@tablename, i.indid, 11) or
c.name = index_col (@tablename, i.indid, 12) or
c.name = index_col (@tablename, i.indid, 13) or
c.name = index_col (@tablename, i.indid, 14) or
c.name = index_col (@tablename, i.indid, 15) or
c.name = index_col (@tablename, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid




-----------------------------------------------------

print 'Option Explicit'
print 'Option Compare Text'
print 'Option Base 0'

print ''

PRINT '''Passed parameters...'

print 'Public ParentForm As Object'

PRINT '''...passed parameters'

print ''

print 'Private m_IsDataExisting as Boolean'

print ''



PRINT 'Private Sub Form_Load()'

PRINT ''

PRINT @Tab + 'Set Me.Icon = LoadPicture("")'

PRINT ''

PRINT 'End Sub'

PRINT ''



PRINT 'Private Sub Form_Activate()'

PRINT ''

PRINT @Tab + 'ParentForm.MessageToUser "' + @TableTransactName + ' ready."'

PRINT ''

PRINT 'End Sub'


PRINT ''

PRINT ''

DECLARE @c CURSOR

DECLARE @C_ReferencedTableName VARCHAR(100)

SET @C = CURSOR FOR
SELECT SC.Name, SC.XType, dt.VbType, ReferencedTableName = rt.name, sc.length
FROM syscolumns AS SC
INNER JOIN systypes AS ST ON sc.xtype = st.xtype
INNER JOIN CodeGen_DataTypes AS dt ON dt.sqltype = st.name
INNER JOIN sysforeignkeys AS sfk ON sfk.fkeyid = sc.id AND sfk.fkey = sc.colid
INNER JOIN sysobjects AS rt ON rt.id = sfk.rkeyid
WHERE sc.id = object_id(@TableName)
AND SC.iscomputed = 0
AND CHARINDEX('_', SC.Name) = 0
ORDER BY SC.colid


DECLARE @S VARCHAR(8000)


DECLARE @PkFieldsMtParameter VARCHAR(8000)

set @PkFieldsMtParameter = NULL

select
@PkFieldsMtParameter = coalesce(
@PkFieldsMtParameter + ', ' + c.Name
, c.Name )
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@tablename)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@tablename, i.indid, c1.colid)
and (c.name = index_col (@tablename, i.indid, 1) or
c.name = index_col (@tablename, i.indid, 2) or
c.name = index_col (@tablename, i.indid, 3) or
c.name = index_col (@tablename, i.indid, 4) or
c.name = index_col (@tablename, i.indid, 5) or
c.name = index_col (@tablename, i.indid, 6) or
c.name = index_col (@tablename, i.indid, 7) or
c.name = index_col (@tablename, i.indid, 8) or
c.name = index_col (@tablename, i.indid, 9) or
c.name = index_col (@tablename, i.indid, 10) or
c.name = index_col (@tablename, i.indid, 11) or
c.name = index_col (@tablename, i.indid, 12) or
c.name = index_col (@tablename, i.indid, 13) or
c.name = index_col (@tablename, i.indid, 14) or
c.name = index_col (@tablename, i.indid, 15) or
c.name = index_col (@tablename, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid


DECLARE @PkFieldsOpenParameter VARCHAR(8000)
set @PkFieldsOpenParameter = NULL
select
@PkFieldsOpenParameter = coalesce(
@PkFieldsOpenParameter + ', Rs.Fields("' + c.Name + '").Value'
, 'Rs.Fields("' + c.Name + '").Value')
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@tablename)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@tablename, i.indid, c1.colid)
and (c.name = index_col (@tablename, i.indid, 1) or
c.name = index_col (@tablename, i.indid, 2) or
c.name = index_col (@tablename, i.indid, 3) or
c.name = index_col (@tablename, i.indid, 4) or
c.name = index_col (@tablename, i.indid, 5) or
c.name = index_col (@tablename, i.indid, 6) or
c.name = index_col (@tablename, i.indid, 7) or
c.name = index_col (@tablename, i.indid, 8) or
c.name = index_col (@tablename, i.indid, 9) or
c.name = index_col (@tablename, i.indid, 10) or
c.name = index_col (@tablename, i.indid, 11) or
c.name = index_col (@tablename, i.indid, 12) or
c.name = index_col (@tablename, i.indid, 13) or
c.name = index_col (@tablename, i.indid, 14) or
c.name = index_col (@tablename, i.indid, 15) or
c.name = index_col (@tablename, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid




DECLARE @PkFieldsFirstKey VARCHAR(8000)
set @PkFieldsFirstKey = NULL
select
TOP 1 @PkFieldsFirstKey = C.Name
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@tablename)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@tablename, i.indid, c1.colid)
and (c.name = index_col (@tablename, i.indid, 1) or
c.name = index_col (@tablename, i.indid, 2) or
c.name = index_col (@tablename, i.indid, 3) or
c.name = index_col (@tablename, i.indid, 4) or
c.name = index_col (@tablename, i.indid, 5) or
c.name = index_col (@tablename, i.indid, 6) or
c.name = index_col (@tablename, i.indid, 7) or
c.name = index_col (@tablename, i.indid, 8) or
c.name = index_col (@tablename, i.indid, 9) or
c.name = index_col (@tablename, i.indid, 10) or
c.name = index_col (@tablename, i.indid, 11) or
c.name = index_col (@tablename, i.indid, 12) or
c.name = index_col (@tablename, i.indid, 13) or
c.name = index_col (@tablename, i.indid, 14) or
c.name = index_col (@tablename, i.indid, 15) or
c.name = index_col (@tablename, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid



declare @PkFieldsFeParameter varchar(8000)
set @PkFieldsFeParameter = NULL

select
@PkFieldsFeParameter = coalesce(
@PkFieldsFeParameter + ', ByVal ' + c.Name + ' As String'
,'ByVal ' + c.Name + ' As String')
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@tablename)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@tablename, i.indid, c1.colid)
and (c.name = index_col (@tablename, i.indid, 1) or
c.name = index_col (@tablename, i.indid, 2) or
c.name = index_col (@tablename, i.indid, 3) or
c.name = index_col (@tablename, i.indid, 4) or
c.name = index_col (@tablename, i.indid, 5) or
c.name = index_col (@tablename, i.indid, 6) or
c.name = index_col (@tablename, i.indid, 7) or
c.name = index_col (@tablename, i.indid, 8) or
c.name = index_col (@tablename, i.indid, 9) or
c.name = index_col (@tablename, i.indid, 10) or
c.name = index_col (@tablename, i.indid, 11) or
c.name = index_col (@tablename, i.indid, 12) or
c.name = index_col (@tablename, i.indid, 13) or
c.name = index_col (@tablename, i.indid, 14) or
c.name = index_col (@tablename, i.indid, 15) or
c.name = index_col (@tablename, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid







PRINT '''User initiated events...'

print 'Private Sub cmdDelete_Click()'
PRINT @Tab + 'DoDelete'
PRINT 'End Sub'

PRINT 'Private Sub cmdSave_Click()'
PRINT @Tab + 'DoSave'
PRINT 'End Sub'

PRINT 'Private Sub cmdNew_Click()'
PRINT @Tab + 'DoNew'
PRINT 'End Sub'

PRINT ''

PRINT 'Private Sub txt' + @PkFieldsFirstKey + '_DropDown(UseDefault As Boolean, RS As ADODB.Recordset, RecordsetPositioner As String)'

PRINT @TryBlockBegin


PRINT @Tab + 'Dim E As String'
PRINT @Tab + 'Set Rs = Services.' + @TableTransactName + '_Browse(E,"")'

PRINT @TryBlockEnd

PRINT @CatchBlockBegin

PRINT dbo.CodeGenFe_CatchBlockEnd('txt' + @PkFieldsFirstKey + '_Dropdown')

PRINT @FinallyBlockBegin

PRINT @FinallyBlockEnd

PRINT 'End Sub'

PRINT ''

PRINT 'Private Sub txt' + @PkFieldsFirstKey + '_GotoRecord(RS As ADODB.Recordset)'

PRINT @TryBlockBegin

PRINT @Tab + 'DoOpen ' + @PkFieldsOpenParameter

PRINT @TryBlockEnd

PRINT @CatchBlockBegin

PRINT dbo.CodeGenFe_CatchBlockEnd('txt' + @PkFieldsFirstKey + '_GotoRecord')

PRINT @FinallyBlockBegin

PRINT @FinallyBlockEnd

PRINT 'End Sub'

PRINT ''


PRINT '''...User initiated events'


DECLARE @C_Name AS VARCHAR(100)
DECLARE @C_XType AS INT
DECLARE @C_VbType VARCHAR(100)
DECLARE @C_Length INT



---------------------
-- generate lookup...

PRINT ''

PRINT '''Lookups...'

OPEN @C

FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_ReferencedTableName, @C_length
WHILE @@FETCH_STATUS = 0 BEGIN



IF EXISTS(


select
*
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@tablename)
AND C.NAME = @C_name
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@tablename, i.indid, c1.colid)
and (c.name = index_col (@tablename, i.indid, 1) or
c.name = index_col (@tablename, i.indid, 2) or
c.name = index_col (@tablename, i.indid, 3) or
c.name = index_col (@tablename, i.indid, 4) or
c.name = index_col (@tablename, i.indid, 5) or
c.name = index_col (@tablename, i.indid, 6) or
c.name = index_col (@tablename, i.indid, 7) or
c.name = index_col (@tablename, i.indid, 8) or
c.name = index_col (@tablename, i.indid, 9) or
c.name = index_col (@tablename, i.indid, 10) or
c.name = index_col (@tablename, i.indid, 11) or
c.name = index_col (@tablename, i.indid, 12) or
c.name = index_col (@tablename, i.indid, 13) or
c.name = index_col (@tablename, i.indid, 14) or
c.name = index_col (@tablename, i.indid, 15) or
c.name = index_col (@tablename, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id



)
BEGIN

GOTO goContinueLookup

END





SET @S = @C_Name

PRINT ''

PRINT 'Private Sub txt' + @C_Name + '_DropDown(UseDefault As Boolean, RS As ADODB.Recordset, RecordsetPositioner As String)'

PRINT @TryBlockBegin
PRINT @Tab + 'Dim E As String'
PRINT @Tab + 'Set Rs = Services.' + @C_ReferencedTableName + '_Lookup(E,"")'
PRINT @Tab + 'RaiseIfErr E'
PRINT @TryBlockEnd


PRINT @CatchBlockBegin

PRINT dbo.CodeGenFe_CatchBlockEnd('txt' + @C_Name + '_DropDown')


PRINT @FinallyBlockBegin

PRINT @FinallyBlockEnd

PRINT 'End Sub'


PRINT ''


PRINT 'Private Sub txt' + @C_Name + '_GotoRecord(Rs As ADODB.Recordset)'

PRINT @Tab + 'txt' + @C_Name + '.Value = Rs.Fields("' + @C_Name + '").Value'

PRINT 'End Sub'

PRINT ''

goContinueLookup:
FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_ReferencedTableName, @C_length
END


CLOSE @C


PRINT '''...Lookups'

PRINT ''

-- ..generate lookup
---------------------

PRINT ''

PRINT '''Transactions...'

PRINT ''


SET @C = CURSOR FOR
SELECT SC.Name, SC.XType, dt.VbType, sc.length
FROM syscolumns AS SC
INNER JOIN systypes AS ST ON sc.xtype = st.xtype
INNER JOIN CodeGen_DataTypes AS dt ON dt.sqltype = st.name
WHERE sc.id = object_id(@TableName)
AND SC.iscomputed = 0
AND CHARINDEX('_', SC.Name) = 0
ORDER BY SC.colid





PRINT 'Private Sub DoNew()'


OPEN @C



DECLARE @Value AS VARCHAR(100)

FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
WHILE @@FETCH_STATUS = 0 BEGIN



IF EXISTS(
select
*
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@tablename)
AND C.NAME = @C_name
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@tablename, i.indid, c1.colid)
and (c.name = index_col (@tablename, i.indid, 1) or
c.name = index_col (@tablename, i.indid, 2) or
c.name = index_col (@tablename, i.indid, 3) or
c.name = index_col (@tablename, i.indid, 4) or
c.name = index_col (@tablename, i.indid, 5) or
c.name = index_col (@tablename, i.indid, 6) or
c.name = index_col (@tablename, i.indid, 7) or
c.name = index_col (@tablename, i.indid, 8) or
c.name = index_col (@tablename, i.indid, 9) or
c.name = index_col (@tablename, i.indid, 10) or
c.name = index_col (@tablename, i.indid, 11) or
c.name = index_col (@tablename, i.indid, 12) or
c.name = index_col (@tablename, i.indid, 13) or
c.name = index_col (@tablename, i.indid, 14) or
c.name = index_col (@tablename, i.indid, 15) or
c.name = index_col (@tablename, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id



)
BEGIN

PRINT + @Tab + 'txt' + @C_Name + '.IsEditable = True'

END




SET @S = @C_Name


IF @C_XType IN (127,106,62,56,60,108,59,52,122,48) BEGIN
SET @Value = '0'
END
ELSE IF @C_XType = 104 BEGIN
SET @Value = 'False'
END
ELSE BEGIN
SET @Value = '""'
END


PRINT @Tab + 'txt' + @S + '.Value = ' + @Value




FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
END

PRINT @Tab + 'm_IsDataExisting = False'


PRINT @Tab + 'ParentForm.MessageToUser "New ' + @TableName + ' ready."'

PRINT 'End Sub'

PRINT ''

CLOSE @C









PRINT 'Public Sub DoOpen(' + @PkFieldsFeParameter + ')'

PRINT @TryBlockBegin

PRINT @Tab + 'Dim Rs As ADODB.Recordset'

PRINT ''


PRINT @Tab + 'Dim E As String'

PRINT @Tab + 'Services.' + @TableName + '_Open E, "", ' + @PkFieldsMtParameter + ', Rs'
PRINT @Tab + 'RaiseIfErr E'


PRINT @Tab + 'If Rs.RecordCount = 1 Then'

OPEN @C


FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
WHILE @@FETCH_STATUS = 0 BEGIN

IF EXISTS(
select
*
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@tablename)
and c.name = @C_Name
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@tablename, i.indid, c1.colid)
and (c.name = index_col (@tablename, i.indid, 1) or
c.name = index_col (@tablename, i.indid, 2) or
c.name = index_col (@tablename, i.indid, 3) or
c.name = index_col (@tablename, i.indid, 4) or
c.name = index_col (@tablename, i.indid, 5) or
c.name = index_col (@tablename, i.indid, 6) or
c.name = index_col (@tablename, i.indid, 7) or
c.name = index_col (@tablename, i.indid, 8) or
c.name = index_col (@tablename, i.indid, 9) or
c.name = index_col (@tablename, i.indid, 10) or
c.name = index_col (@tablename, i.indid, 11) or
c.name = index_col (@tablename, i.indid, 12) or
c.name = index_col (@tablename, i.indid, 13) or
c.name = index_col (@tablename, i.indid, 14) or
c.name = index_col (@tablename, i.indid, 15) or
c.name = index_col (@tablename, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id

)
BEGIN

PRINT + @Tab + @Tab + 'txt' + @C_Name + '.IsEditable = False'

END


SET @S = @C_Name

PRINT @Tab + @Tab + 'txt' + @C_Name + '.Value = Rs.Fields("' + @C_Name + '").Value'



FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
END





PRINT @Tab + @Tab + 'm_IsDataExisting = True'


PRINT @Tab + @Tab + 'ParentForm.MessageToUser "Existing ' + @TableName + ' ready."'

CLOSE @C

PRINT @Tab + 'End If'


PRINT @TryBlockEnd

PRINT ''

PRINT @CatchBlockBegin


PRINT dbo.CodeGenFe_CatchBlockEnd('DoOpen')

PRINT ''

PRINT @FinallyBlockBegin

PRINT ''

PRINT @FinallyBlockEnd

PRINT 'End Sub'

PRINT ''





PRINT 'Private Sub DoDelete()'

PRINT @TryBlockBegin


print @pkdeclare

PRINT ''

declare @PkDisplay varchar(8000)

set @PkDisplay = NULL
select
@PkDisplay = coalesce(
@PkDisplay + ' & " " & ' + c.Name
,c.Name )
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@tablename)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@tablename, i.indid, c1.colid)
and (c.name = index_col (@tablename, i.indid, 1) or
c.name = index_col (@tablename, i.indid, 2) or
c.name = index_col (@tablename, i.indid, 3) or
c.name = index_col (@tablename, i.indid, 4) or
c.name = index_col (@tablename, i.indid, 5) or
c.name = index_col (@tablename, i.indid, 6) or
c.name = index_col (@tablename, i.indid, 7) or
c.name = index_col (@tablename, i.indid, 8) or
c.name = index_col (@tablename, i.indid, 9) or
c.name = index_col (@tablename, i.indid, 10) or
c.name = index_col (@tablename, i.indid, 11) or
c.name = index_col (@tablename, i.indid, 12) or
c.name = index_col (@tablename, i.indid, 13) or
c.name = index_col (@tablename, i.indid, 14) or
c.name = index_col (@tablename, i.indid, 15) or
c.name = index_col (@tablename, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid

PRINT @Tab + 'Dim E As String'

PRINT @Tab + 'If m_IsDataExisting Then'
PRINT @Tab + @Tab + 'If MsgBox("Are you sure you do want to delete " & ' + @PkDisplay + ', vbQuestion + vbYesNo + vbDefaultButton2, "Deleting Record") = vbYes Then'

PRINT ''

PRINT @Tab + @Tab + @Tab + 'Services.' + @TableTransactName + '_Delete E, "", ' + @PkFieldsMtParameter

PRINT @Tab + @Tab + @Tab + 'RaiseIfErr E'

PRINT @Tab + @Tab + @Tab + 'DoNew'

PRINT ''

PRINT @Tab + @Tab + 'End If'

PRINT @Tab + 'End If'



PRINT ''

PRINT @TryBlockEnd

PRINT ''


PRINT @CatchBlockBegin


PRINT dbo.CodeGenFe_CatchBlockEnd('DoDelete')

PRINT ''


PRINT @FinallyBlockBegin


PRINT @FinallyBlockEnd


PRINT 'End Sub'


PRINT ''

PRINT 'Private Function IsInputValid() As Boolean'


print @Tab + 'IsInputValid = False'


OPEN @C


FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
WHILE @@FETCH_STATUS = 0 BEGIN



-- numbers
IF @C_XType IN (127,106,62,56,60,108,59,52,122,48) BEGIN
print ''
END
ELSE IF @C_XType = 104 BEGIN -- boolean
PRINT ''
END
-- date
ELSE IF @C_XType IN (61, 58) BEGIN
PRINT @Tab + 'If Not txt' + @C_Name + '.ReadOnly And IsNull(txt' + @C_Name + '.Value) Then'
PRINT @Tab + @Tab + 'ParentForm.MessageToUser "' + @C_Name + ' can''t be left blank"'
PRINT @Tab + @Tab + 'txt' + @C_Name + '.SetFocus'
PRINT @Tab + @Tab + 'Exit Function'
PRINT @Tab + 'End If'
END
ELSE BEGIN
PRINT @Tab + 'If Not txt' + @C_Name + '.ReadOnly And txt' + @C_Name + '.Value = "" Then'
PRINT @Tab + @Tab + 'ParentForm.MessageToUser "' + @C_Name + ' can''t be left blank"'
PRINT @Tab + @Tab + 'txt' + @C_Name + '.SetFocus'
PRINT @Tab + @Tab + 'Exit Function'
PRINT @Tab + 'End If'
END





FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
END


CLOSE @C


PRINT @Tab + '''Put other validations here...'


PRINT @Tab + '''...Put other validations here'

PRINT @Tab + 'IsInputValid = True'


PRINT 'End Function'


PRINT ''

PRINT 'Private Sub DoSave()'



PRINT @Tab + 'If Not IsInputValid() Then'

PRINT @Tab + @Tab + 'Exit Sub'

PRINT @Tab + 'End If'





PRINT @PkDeclare

PRINT ''


PRINT @TryBlockBegin

PRINT @Tab + 'Dim IsExists As Boolean'
PRINT @Tab + 'Dim E As String'
PRINT @Tab + 'IsExists = Services.' + @TableName + '_IsExisting(E, "", ' + @PkFieldsMtParameter + ')'
PRINT @Tab + 'RaiseIfErr E'

PRINT ''

PRINT @Tab + 'If m_IsDataExisting Then '

PRINT @Tab + @Tab + 'If Not IsExists Then'

PRINT @Tab + @Tab + @Tab + 'MsgBox ' + @PkDisplay + ' & " is already deleted before you have even saved", vbInformation'

PRINT @Tab + @Tab + @Tab + 'GoTo goFinally'

PRINT @Tab + @Tab + 'End If'

PRINT @Tab + 'Else'

PRINT @Tab + @Tab + 'If IsExists Then'

PRINT @Tab + @Tab + @Tab + 'MsgBox ' + @PkDisplay + ' & " already in the database", vbInformation'

PRINT @Tab + @Tab + @Tab + 'GoTo goFinally'

PRINT @Tab + @Tab + 'End If'

PRINT @Tab + 'End If'


------------------------
PRINT ''

PRINT @Tab + 'Dim RsSrc As ADODB.Recordset'
PRINT @Tab + 'Set RsSrc = New ADODB.Recordset'



OPEN @C

FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
WHILE @@FETCH_STATUS = 0 BEGIN


IF EXISTS(


select
*
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@tablename)
AND C.NAME = @C_name
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@tablename, i.indid, c1.colid)
and (c.name = index_col (@tablename, i.indid, 1) or
c.name = index_col (@tablename, i.indid, 2) or
c.name = index_col (@tablename, i.indid, 3) or
c.name = index_col (@tablename, i.indid, 4) or
c.name = index_col (@tablename, i.indid, 5) or
c.name = index_col (@tablename, i.indid, 6) or
c.name = index_col (@tablename, i.indid, 7) or
c.name = index_col (@tablename, i.indid, 8) or
c.name = index_col (@tablename, i.indid, 9) or
c.name = index_col (@tablename, i.indid, 10) or
c.name = index_col (@tablename, i.indid, 11) or
c.name = index_col (@tablename, i.indid, 12) or
c.name = index_col (@tablename, i.indid, 13) or
c.name = index_col (@tablename, i.indid, 14) or
c.name = index_col (@tablename, i.indid, 15) or
c.name = index_col (@tablename, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id



)
BEGIN

GOTO goContinueType

END






SET @S = @C_Name



IF @C_XType IN (127,106,62,56,60,108,59,52,122,48) BEGIN
PRINT @Tab + 'RsSrc.Fields.Append "' + @C_Name + '", ' + @C_VbType
END
ELSE IF @C_XType = 104 BEGIN -- boolean
PRINT @Tab + 'RsSrc.Fields.Append "' + @C_Name + '", ' + @C_VbType
END
ELSE BEGIN
PRINT @Tab + 'RsSrc.Fields.Append "' + @C_Name + '", ' + @C_VbType + ', ' + CONVERT(VARCHAR,@C_Length)
END





goContinueType:
FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
END


CLOSE @C

PRINT @Tab + 'RsSrc.Open'

PRINT ''



------------------------





PRINT @Tab + 'RsSrc.AddNew'

OPEN @C

FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
WHILE @@FETCH_STATUS = 0 BEGIN


IF EXISTS(


select
*
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@tablename)
AND C.NAME = @C_name
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@tablename, i.indid, c1.colid)
and (c.name = index_col (@tablename, i.indid, 1) or
c.name = index_col (@tablename, i.indid, 2) or
c.name = index_col (@tablename, i.indid, 3) or
c.name = index_col (@tablename, i.indid, 4) or
c.name = index_col (@tablename, i.indid, 5) or
c.name = index_col (@tablename, i.indid, 6) or
c.name = index_col (@tablename, i.indid, 7) or
c.name = index_col (@tablename, i.indid, 8) or
c.name = index_col (@tablename, i.indid, 9) or
c.name = index_col (@tablename, i.indid, 10) or
c.name = index_col (@tablename, i.indid, 11) or
c.name = index_col (@tablename, i.indid, 12) or
c.name = index_col (@tablename, i.indid, 13) or
c.name = index_col (@tablename, i.indid, 14) or
c.name = index_col (@tablename, i.indid, 15) or
c.name = index_col (@tablename, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id



)
BEGIN

GOTO goContinue

END






SET @S = @C_Name

PRINT @Tab + 'RsSrc.Fields("' + @S + '").Value = txt' + @S + '.Value'


goContinue:
FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
END


CLOSE @C

PRINT @Tab + 'RsSrc.Update'

PRINT ''

PRINT @Tab + 'ParentForm.MessageToUser "' + @TableName + ' saving..."'

PRINT @Tab + 'Services.' + @TableName + '_Save E, "", m_IsDataExisting, ' + @PkFieldsMtParameter + ', RsSrc'
PRINT @Tab + 'RaiseIfErr E'

PRINT ''






DECLARE @PkEditable VARCHAR(8000)
set @PkEditable = ''
select
@PkEditable =
@PkEditable + @Tab + 'txt' + c.Name + '.IsEditable = False' + CHAR(13)
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@tablename)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@tablename, i.indid, c1.colid)
and (c.name = index_col (@tablename, i.indid, 1) or
c.name = index_col (@tablename, i.indid, 2) or
c.name = index_col (@tablename, i.indid, 3) or
c.name = index_col (@tablename, i.indid, 4) or
c.name = index_col (@tablename, i.indid, 5) or
c.name = index_col (@tablename, i.indid, 6) or
c.name = index_col (@tablename, i.indid, 7) or
c.name = index_col (@tablename, i.indid, 8) or
c.name = index_col (@tablename, i.indid, 9) or
c.name = index_col (@tablename, i.indid, 10) or
c.name = index_col (@tablename, i.indid, 11) or
c.name = index_col (@tablename, i.indid, 12) or
c.name = index_col (@tablename, i.indid, 13) or
c.name = index_col (@tablename, i.indid, 14) or
c.name = index_col (@tablename, i.indid, 15) or
c.name = index_col (@tablename, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid


PRINT @PkEditable

PRINT @Tab + 'm_IsDataExisting = True'

PRINT @Tab + 'ParentForm.MessageToUser "' + @TableName + ' saved."'
PRINT @Tab + 'MsgBox "' + @TableName + ' saved.", vbInformation'

PRINT @TryBlockEnd

PRINT @CatchBlockBegin

PRINT @Tab + 'ParentForm.MessageToUser ""'

PRINT dbo.CodeGenFe_CatchBlockEnd('DoSave')

PRINT @FinallyBlockBegin


PRINT @FinallyBlockEnd

PRINT 'End Sub'

PRINT ''

PRINT '''...Transactions'

----------------------

DEALLOCATE @C























GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO





















CREATE PROCEDURE CodeGenFe_TwoTableNoAutoId
@TransactName VARCHAR(100),
@TableHeaderName VARCHAR(100),
@TableDetailName VARCHAR(100)
AS

IF object_id(@TableHeaderName) IS NULL BEGIN
PRINT 'Table ' + @TableHeaderName + ' does not exists'
RETURN
END

IF object_id(@TableDetailName) IS NULL BEGIN
PRINT 'Table ' + @TableDetailName + ' does not exists'
RETURN
END





DECLARE @Tab VARCHAR(4)
SET @Tab = SPACE(4)



DECLARE @TryBlockBegin VARCHAR(8000)

SET @TryBlockBegin = @Tab + 'On Error GoTo goCatchError'
+ CHAR(13)
+ @Tab + '''Try{' + CHAR(13) + CHAR(13)

DECLARE @TryBlockEnd VARCHAR(8000)

SET @TryBlockEnd = CHAR(13) + @Tab + 'GoTo goFinally' + CHAR(13) + @Tab + '''}' + CHAR(13)


DECLARE @CatchBlockBegin VARCHAR(8000)

SET @CatchBlockBegin= @Tab + '''CatchError{' + CHAR(13) + 'goCatchError:' + CHAR(13) + CHAR(13) + char(13)

+ @Tab + 'Screen.MousePointer = vbDefault'






DECLARE @FinallyBlockBegin VARCHAR(8000)

SET @FinallyBlockBegin = @Tab + '''Finally{' + CHAR(13) + 'goFinally:' + CHAR(13) + CHAR(13)

DECLARE @FinallyBlockEnd VARCHAR(8000)

SET @FinallyBlockEnd = @Tab + '''}'




DECLARE @PkDeclare VARCHAR(8000)

set @PkDeclare = ''
select
@PkDeclare = @PkDeclare + CHAR(13) + @Tab + 'Dim ' + c.Name + ' As String'
+ CHAR(13) + @Tab + C.Name + ' = txt' + C.Name + '.Value'
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
and o.id = c.id
and o.id = i.id


and c.name NOT IN (SELECT GeographicCode FROM CodeGen_Geographic)

and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid




-----------------------------------------------------

print 'Option Explicit'
print 'Option Compare Text'
print 'Option Base 0'

PRINT ''
PRINT '''Passed parameters...'

print 'Public ParentForm As Object'

PRINT '''...passed parameters'

print ''


PRINT 'Private Const m_grdGotFocusColor = &HFF0000'
PRINT 'Private Const m_grdLostFocusColor = 0'

print ''


print 'Private m_IsDataExisting as Boolean'
PRINT 'Private m_RsDeleted As ADODB.Recordset'

print ''



PRINT 'Private Sub Form_Load()'

PRINT ''

PRINT @Tab + 'Set Me.Icon = LoadPicture("")'

PRINT ''

PRINT 'End Sub'

PRINT ''



PRINT 'Private Sub Form_Activate()'

PRINT ''

PRINT @Tab + 'ParentForm.ShowMessage "' + @TransactName + ' ready."'

PRINT ''

PRINT 'End Sub'


PRINT ''

PRINT ''

DECLARE @c CURSOR

DECLARE @C_ReferencedTableName VARCHAR(100)

SET @C = CURSOR FOR
SELECT SC.Name, SC.XType, dt.VbType, ReferencedTableName = rt.name, sc.length
FROM syscolumns AS SC
INNER JOIN systypes AS ST ON sc.xtype = st.xtype
INNER JOIN CodeGen_DataTypes AS dt ON dt.sqltype = st.name
INNER JOIN sysforeignkeys AS sfk ON sfk.fkeyid = sc.id AND sfk.fkey = sc.colid
INNER JOIN sysobjects AS rt ON rt.id = sfk.rkeyid
WHERE sc.id = object_id(@TableHeaderName)
AND SC.iscomputed = 0
AND CHARINDEX('_', SC.Name) = 0
ORDER BY SC.colid


DECLARE @S VARCHAR(8000)


DECLARE @PkFieldsMtParameter VARCHAR(8000)

set @PkFieldsMtParameter = NULL

select
@PkFieldsMtParameter = coalesce(
@PkFieldsMtParameter + ', ' + c.Name
, c.Name )
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid


DECLARE @PkFieldsOpenParameter VARCHAR(8000)
set @PkFieldsOpenParameter = NULL
select
@PkFieldsOpenParameter = coalesce(
@PkFieldsOpenParameter + ', Rs.Fields("' + c.Name + '").Value'
, 'Rs.Fields("' + c.Name + '").Value')
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid




DECLARE @PkFieldsFirstKey VARCHAR(8000)
set @PkFieldsFirstKey = NULL
select
TOP 1 @PkFieldsFirstKey = C.Name
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid



declare @PkFieldsFeParameter varchar(8000)
set @PkFieldsFeParameter = NULL

select
@PkFieldsFeParameter = coalesce(
@PkFieldsFeParameter + ', ByVal ' + c.Name + ' As String'
,'ByVal ' + c.Name + ' As String')
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid







PRINT '''User initiated events...'

print 'Private Sub cmdDelete_Click()'
PRINT @Tab + 'DoDelete'
PRINT 'End Sub'

PRINT 'Private Sub cmdSave_Click()'
PRINT @Tab + 'DoSave'
PRINT 'End Sub'

PRINT 'Private Sub cmdNew_Click()'
PRINT @Tab + 'DoNew'
PRINT 'End Sub'

PRINT ''

PRINT 'Private Sub txt' + @PkFieldsFirstKey + '_DropDown(UseDefault As Boolean, RS As ADODB.Recordset, RecordsetPositioner As String)'

PRINT @TryBlockBegin


PRINT @Tab + 'Dim E As String'
PRINT @Tab + 'Set Rs = Services.' + @TransactName + '_Browse(E,"")'

PRINT @TryBlockEnd

PRINT @CatchBlockBegin

PRINT dbo.CodeGenFe_CatchBlockEnd('txt' + @PkFieldsFirstKey + '_Dropdown')

PRINT @FinallyBlockBegin

PRINT @FinallyBlockEnd

PRINT 'End Sub'

PRINT ''

PRINT 'Private Sub txt' + @PkFieldsFirstKey + '_GotoRecord(RS As ADODB.Recordset)'

PRINT @TryBlockBegin

PRINT @Tab + 'DoOpen ' + @PkFieldsOpenParameter

PRINT @TryBlockEnd

PRINT @CatchBlockBegin

PRINT dbo.CodeGenFe_CatchBlockEnd('txt' + @PkFieldsFirstKey + '_GotoRecord')

PRINT @FinallyBlockBegin

PRINT @FinallyBlockEnd

PRINT 'End Sub'

PRINT ''



PRINT 'Private Sub cmdClone_Click()'
PRINT @Tab + 'DoClone'
PRINT 'End Sub'

PRINT ''

PRINT 'Private Sub DoClone()'
PRINT @Tab + 'm_IsDataExisting = False'


declare @PkClonePrimaryKeys varchar(8000)
set @PkClonePrimaryKeys = ''
select
@PkClonePrimaryKeys =
@PkClonePrimaryKeys + CHAR(13) +
CHAR(13) + @Tab + 'txt' + c.Name + '.Value = ""' +
CHAR(13) + @Tab + 'txt' + c.Name + '.IsEditable = True'
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid

PRINT @PkClonePrimaryKeys

PRINT ''

PRINT @Tab + 'SetGridIsChangedStatus grd, True'

PRINT 'End Sub'



PRINT '''...User initiated events'


DECLARE @C_Name AS VARCHAR(100)
DECLARE @C_XType AS INT
DECLARE @C_VbType VARCHAR(100)
DECLARE @C_Length INT



---------------------
-- generate lookup...

PRINT ''

PRINT '''Lookups...'

OPEN @C

FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_ReferencedTableName, @C_length
WHILE @@FETCH_STATUS = 0 BEGIN



IF EXISTS(


select
*
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
AND C.NAME = @C_name
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id



)
BEGIN

GOTO goContinueLookup

END





SET @S = @C_Name

PRINT ''

PRINT 'Private Sub txt' + @C_Name + '_DropDown(UseDefault As Boolean, RS As ADODB.Recordset, RecordsetPositioner As String)'

PRINT @TryBlockBegin
PRINT @Tab + 'Dim E As String'
PRINT @Tab + 'Set Rs = Services.' + @C_ReferencedTableName + '_Lookup(E,"")'
PRINT @Tab + 'RaiseIfErr E'
PRINT @TryBlockEnd


PRINT @CatchBlockBegin

PRINT dbo.CodeGenFe_CatchBlockEnd('txt' + @C_Name + '_DropDown')


PRINT @FinallyBlockBegin

PRINT @FinallyBlockEnd

PRINT 'End Sub'


PRINT ''


PRINT 'Private Sub txt' + @C_Name + '_GotoRecord(Rs As ADODB.Recordset)'

PRINT @Tab + 'txt' + @C_Name + '.Value = Rs.Fields("' + @C_Name + '").Value'

PRINT 'End Sub'

PRINT ''

goContinueLookup:
FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_ReferencedTableName, @C_length
END


CLOSE @C


PRINT '''...Lookups'

PRINT ''

-- ..generate lookup
---------------------

PRINT ''

PRINT '''Transactions...'

PRINT ''


SET @C = CURSOR FOR
SELECT SC.Name, SC.XType, dt.VbType, sc.length
FROM syscolumns AS SC
INNER JOIN systypes AS ST ON sc.xtype = st.xtype
INNER JOIN CodeGen_DataTypes AS dt ON dt.sqltype = st.name
WHERE sc.id = object_id(@TableHeaderName)
AND SC.iscomputed = 0
AND
(
PATINDEX('%_QTY', SC.Name) = 0
AND PATINDEX('%_COST', SC.Name) = 0
AND PATINDEX('%_PRICE', SC.Name) = 0
)
ORDER BY SC.colid





PRINT 'Private Sub DoNew()'


OPEN @C



DECLARE @Value AS VARCHAR(100)

FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
WHILE @@FETCH_STATUS = 0 BEGIN



IF EXISTS(
select
*
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
AND C.NAME = @C_name
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id



)
BEGIN

PRINT + @Tab + 'txt' + @C_Name + '.IsEditable = True'

END




SET @S = @C_Name


IF @C_XType IN (127,106,62,56,60,108,59,52,122,148) BEGIN
SET @Value = '0'
END
ELSE IF @C_XType = 104 BEGIN
SET @Value = 'False'
END
ELSE BEGIN
SET @Value = '""'
END


PRINT @Tab + 'txt' + @S + '.Value = ' + @Value




FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
END

PRINT @Tab + 'grd.RemoveAll'

PRINT @Tab + 'm_IsDataExisting = False'


PRINT @Tab + 'ParentForm.ShowMessage "New ' + @TransactName + ' ready."'

PRINT 'End Sub'

PRINT ''

CLOSE @C









PRINT 'Public Sub DoOpen(' + @PkFieldsFeParameter + ')'

PRINT @TryBlockBegin

PRINT @Tab + 'Dim RsHeader As ADODB.Recordset'
PRINT @Tab + 'Dim RsDetail AS ADODB.Recordset'

PRINT ''


PRINT @Tab + 'Dim E As String'

PRINT @Tab + 'Services.' + @TransactName + '_Open E, "", ' + @PkFieldsMtParameter + ', RsHeader'
PRINT @Tab + 'RaiseIfErr E'


PRINT @Tab + 'If RsHeader.RecordCount = 1 Then'

OPEN @C


FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
WHILE @@FETCH_STATUS = 0 BEGIN

IF EXISTS(
select
*
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
and c.name = @C_Name
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id

)
BEGIN

PRINT + @Tab + @Tab + 'txt' + @C_Name + '.IsEditable = False'

END


SET @S = @C_Name

PRINT @Tab + @Tab + 'txt' + @C_Name + '.Value = RsHeader.Fields("' + @C_Name + '").Value'



FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
END



PRINT @Tab + @Tab + 'MycFunc4Ctrls.ScatterRecordsetToGrid grd, RsDetail, False'

PRINT @Tab + @Tab + 'm_IsDataExisting = True'




PRINT @Tab + @Tab + 'ParentForm.ShowMessage "Existing ' + @TransactName + ' ready."'

CLOSE @C

PRINT @Tab + 'End If'


PRINT @TryBlockEnd

PRINT ''

PRINT @CatchBlockBegin


PRINT dbo.CodeGenFe_CatchBlockEnd('DoOpen')

PRINT ''

PRINT @FinallyBlockBegin

PRINT ''

PRINT @FinallyBlockEnd

PRINT 'End Sub'

PRINT ''





PRINT 'Private Sub DoDelete()'

PRINT @TryBlockBegin


print @pkdeclare

PRINT ''

declare @PkDisplay varchar(8000)

set @PkDisplay = NULL
select
@PkDisplay = coalesce(
@PkDisplay + ' & " " & ' + c.Name
,c.Name )
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid

PRINT @Tab + 'Dim E As String'

PRINT @Tab + 'If m_IsDataExisting Then'
PRINT @Tab + @Tab + 'If MsgBox("Are you sure you do want to delete " & ' + @PkDisplay + ', vbQuestion + vbYesNo + vbDefaultButton2, "Deleting Record") = vbYes Then'

PRINT ''

PRINT @Tab + @Tab + @Tab + 'Services.' + @TransactName + '_Delete E, "", ' + @PkFieldsMtParameter

PRINT @Tab + @Tab + @Tab + 'RaiseIfErr E'

PRINT @Tab + @Tab + @Tab + 'DoNew'

PRINT ''

PRINT @Tab + @Tab + 'End If'

PRINT @Tab + 'End If'



PRINT ''

PRINT @TryBlockEnd

PRINT ''


PRINT @CatchBlockBegin


PRINT dbo.CodeGenFe_CatchBlockEnd('DoDelete')

PRINT ''


PRINT @FinallyBlockBegin


PRINT @FinallyBlockEnd


PRINT 'End Sub'


PRINT ''

PRINT 'Private Function IsInputValid() As Boolean'


print @Tab + 'IsInputValid = False'


OPEN @C


FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
WHILE @@FETCH_STATUS = 0 BEGIN



-- numbers
IF @C_XType IN (127,106,62,56,60,108,59,52,122,148) BEGIN
print ''
END
ELSE IF @C_XType = 104 BEGIN -- boolean
PRINT ''
END
-- date
ELSE IF @C_XType IN (61, 58) BEGIN
PRINT @Tab + 'If Not txt' + @C_Name + '.ReadOnly And IsNull(txt' + @C_Name + '.Value) Then'
PRINT @Tab + @Tab + 'ParentForm.ShowMessage "' + @C_Name + ' can''t be left blank"'
PRINT @Tab + @Tab + 'txt' + @C_Name + '.SetFocus'
PRINT @Tab + @Tab + 'Exit Function'
PRINT @Tab + 'End If'
END
ELSE BEGIN
PRINT @Tab + 'If Not txt' + @C_Name + '.ReadOnly And txt' + @C_Name + '.Value = "" Then'
PRINT @Tab + @Tab + 'ParentForm.ShowMessage "' + @C_Name + ' can''t be left blank"'
PRINT @Tab + @Tab + 'txt' + @C_Name + '.SetFocus'
PRINT @Tab + @Tab + 'Exit Function'
PRINT @Tab + 'End If'
END





FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
END


CLOSE @C


PRINT @Tab + '''Put other validations here...'


PRINT @Tab + '''...Put other validations here'

PRINT @Tab + 'IsInputValid = True'


PRINT 'End Function'


PRINT ''

PRINT 'Private Sub DoSave()'



PRINT @Tab + 'If Not IsInputValid() Then'

PRINT @Tab + @Tab + 'Exit Sub'

PRINT @Tab + 'End If'





PRINT @PkDeclare

PRINT ''


PRINT @TryBlockBegin

PRINT @Tab + 'Dim IsExists As Boolean'
PRINT @Tab + 'Dim E As String'
PRINT @Tab + 'IsExists = Services.' + @TransactName + '_IsExisting(E, "", ' + @PkFieldsMtParameter + ')'
PRINT @Tab + 'RaiseIfErr E'

PRINT ''

PRINT @Tab + 'If m_IsDataExisting Then '

PRINT @Tab + @Tab + 'If Not IsExists Then'

PRINT @Tab + @Tab + @Tab + 'MsgBox ' + @PkDisplay + ' & " is already deleted before you have even saved", vbInformation'

PRINT @Tab + @Tab + @Tab + 'GoTo goFinally'

PRINT @Tab + @Tab + 'End If'

PRINT @Tab + 'Else'

PRINT @Tab + @Tab + 'If IsExists Then'

PRINT @Tab + @Tab + @Tab + 'MsgBox ' + @PkDisplay + ' & " already in the database", vbInformation'

PRINT @Tab + @Tab + @Tab + 'GoTo goFinally'

PRINT @Tab + @Tab + 'End If'

PRINT @Tab + 'End If'


------------------------
PRINT ''

PRINT @Tab + 'Dim RsHeaderSrc As ADODB.Recordset'
PRINT @Tab + 'Set RsHeaderSrc = New ADODB.Recordset'



OPEN @C

FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
WHILE @@FETCH_STATUS = 0 BEGIN


IF EXISTS(


select
*
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
AND C.NAME = @C_name
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id



)
BEGIN

GOTO goContinueType

END






SET @S = @C_Name



IF @C_XType IN (127,106,62,56,60,108,59,52,122,148) BEGIN
PRINT @Tab + 'RsHeaderSrc.Fields.Append "' + @C_Name + '", ' + @C_VbType
END
ELSE IF @C_XType = 104 BEGIN -- boolean
PRINT @Tab + 'RsHeaderSrc.Fields.Append "' + @C_Name + '", ' + @C_VbType
END
ELSE BEGIN
PRINT @Tab + 'RsHeaderSrc.Fields.Append "' + @C_Name + '", ' + @C_VbType + ', ' + CONVERT(VARCHAR,@C_Length)
END





goContinueType:
FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
END


CLOSE @C

PRINT @Tab + 'RsHeaderSrc.Open'

PRINT ''



------------------------





PRINT @Tab + 'RsHeaderSrc.AddNew'

OPEN @C

FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
WHILE @@FETCH_STATUS = 0 BEGIN


IF EXISTS(


select
*
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
AND C.NAME = @C_name
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id



)
BEGIN

GOTO goContinue

END






SET @S = @C_Name

PRINT @Tab + 'RsHeaderSrc.Fields("' + @S + '").Value = txt' + @S + '.Value'


goContinue:
FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_Length
END


CLOSE @C

PRINT @Tab + 'RsHeaderSrc.Update'

PRINT ''


PRINT @Tab + 'Dim RsDetailSrc As ADODB.Recordset'
PRINT @Tab + 'Set RsDetailSrc = MycFunc4Ctrls.GatherGridToRecordset(grd)'




PRINT @Tab + 'ParentForm.ShowMessage "' + @TransactName + ' saving..."'



PRINT @Tab + 'Services.' + @TransactName + '_Save E, "", m_IsDataExisting, ' + @PkFieldsMtParameter + ', RsHeaderSrc, RsDetailSrc, m_rsDeleted'
PRINT @Tab + 'RaiseIfErr E'

PRINT ''






DECLARE @PkEditable VARCHAR(8000)
set @PkEditable = ''
select
@PkEditable =
@PkEditable + @Tab + 'txt' + c.Name + '.IsEditable = False' + CHAR(13)
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid


PRINT @PkEditable

PRINT @Tab + 'm_IsDataExisting = True'

PRINT @Tab + 'ParentForm.ShowMessage "' + @TransactName + ' saved."'
PRINT @Tab + 'MsgBox "' + @TransactName + ' saved.", vbInformation'

PRINT @TryBlockEnd

PRINT @CatchBlockBegin

PRINT @Tab + 'ParentForm.ShowMessage ""'

PRINT dbo.CodeGenFe_CatchBlockEnd('DoSave')

PRINT @FinallyBlockBegin


PRINT @FinallyBlockEnd

PRINT 'End Sub'

PRINT ''

PRINT '''...Transactions'

----------------------


DEALLOCATE @C


PRINT ''

PRINT ''' Details...'

PRINT ''

PRINT 'Private Sub ComputeAllRows()'

PRINT ''




DECLARE @DetailAggregates AS VARCHAR(8000)
SET @DetailAggregates = ''
SELECT @DetailAggregates =
@DetailAggregates + CHAR(13)
+ @Tab + 'Dim Sum' + c.Name + ' As ' + dt.VbTypeDim + CHAR(13)
+ @Tab + 'Sum' + c.Name + ' = 0'
FROM sysobjects as o
INNER JOIN syscolumns as c ON c.id = o.id
INNER JOIN systypes AS ST ON c.xtype = st.xtype
INNER JOIN CodeGen_DataTypes AS dt ON dt.sqltype = st.name
WHERE o.id = object_id(@TableDetailName)
AND c.iscomputed = 0
AND st.xtype IN (127,106,62,56,60,108,59,52,122,48)
AND CHARINDEX('_', c.Name) = 0
ORDER BY colid



PRINT @DetailAggregates

PRINT ''

PRINT @Tab + 'Dim R As Long'
PRINT @Tab + 'For R = 0 to grd.Rows - 1'

PRINT @Tab + @Tab + 'Dim Bm'

PRINT @Tab + @Tab + 'Bm = grd.AddItemBookmark(R)'

SET @DetailAggregates = ''
SELECT @DetailAggregates =
@DetailAggregates + CHAR(13)
+ @Tab + @Tab + 'Sum' + c.Name + ' = Sum' + C.Name + ' + grd.Columns("' + C.Name + '").CellValue(BM)'
FROM sysobjects as o
INNER JOIN syscolumns as c ON c.id = o.id
INNER JOIN systypes AS ST ON c.xtype = st.xtype
INNER JOIN CodeGen_DataTypes AS dt ON dt.sqltype = st.name
WHERE o.id = object_id(@TableDetailName)
AND c.iscomputed = 0
AND st.xtype IN (127,106,62,56,60,108,59,52,122,48)
AND CHARINDEX('_', c.Name) = 0


PRINT @DetailAggregates

PRINT @Tab + 'Next'



SET @DetailAggregates = ''
SELECT @DetailAggregates =
@DetailAggregates + CHAR(13)
+ @Tab + 'txtSum' + c.Name + '.Value = Sum' + C.Name
FROM sysobjects as o
INNER JOIN syscolumns as c ON c.id = o.id
INNER JOIN systypes AS ST ON c.xtype = st.xtype
INNER JOIN CodeGen_DataTypes AS dt ON dt.sqltype = st.name
WHERE o.id = object_id(@TableDetailName)
AND c.iscomputed = 0
AND st.xtype IN (127,106,62,56,60,108,59,52,122,48)
AND CHARINDEX('_', c.Name) = 0

PRINT @DetailAggregates

PRINT ''


PRINT ''

PRINT 'End Sub'

PRINT ''

PRINT 'Private Sub ComputeRow()'

PRINT @Tab + 'grd.Columns("IsChanged").Value = True'

PRINT @Tab + ''' example: grd.Columns("Amount").Value = grd.Columns("Qty").Value * grd.Columns("UnitPrice").ValuE'

PRINT @Tab + 'grd.Update'

PRINT 'End Sub'

PRINT ''

PRINT 'Private Sub CreateRsDeleteStructure()'

PRINT @Tab + 'If Not (m_rsDeleted Is Nothing) Then'
PRINT @Tab + @Tab + 'm_rsDeleted.Close'
PRINT @Tab + @Tab + 'Set m_rsDeleted = Nothing'
PRINT @Tab + 'End If'


PRINT @Tab + 'Set m_rsDeleted = New ADODB.Recordset'
PRINT @Tab + 'm_rsDeleted.CursorLocation = adUseClient'
PRINT @Tab + 'm_rsDeleted.Fields.Append "RecId", adGUID'
PRINT @Tab + 'm_rsDeleted.Open'


PRINT 'End Sub'

PRINT ''


PRINT 'Private Sub grd_KeyDown(KeyCode As Integer, Shift As Integer)'

PRINT ''
PRINT @Tab + '''grdEnhancement... don''t delete this comment'
PRINT @Tab + 'If KeyCode = vbKeyReturn Then'
PRINT @Tab + @Tab + 'If grd.Col + 1 >= grd.Columns.Count Then'
PRINT @Tab + @Tab + @Tab + ''' wrap to next row and first column'

PRINT ''

PRINT @Tab + @Tab + @Tab + 'grd.Bookmark = grd.GetBookmark(1)'
PRINT @Tab + @Tab + @Tab + 'Dim C As SSDataWidgets_B_OLEDB.Column'
PRINT @Tab + @Tab + @Tab + 'Dim I As Integer'
PRINT @Tab + @Tab + @Tab + 'For I = 0 To grd.Columns.Count - 1'
PRINT @Tab + @Tab + @Tab + @Tab + 'If grd.Columns(I).Visible And Not grd.Columns(I).Locked Then'
PRINT @Tab + @Tab + @Tab + @Tab + @Tab + 'grd.Col = I'
PRINT @Tab + @Tab + @Tab + @Tab + @Tab + 'Exit For'
PRINT @Tab + @Tab + @Tab + @Tab + 'End If'
PRINT @Tab + @Tab + @Tab + 'Next'

PRINT @Tab + @Tab + 'Else'
PRINT @Tab + @Tab + @Tab + '''go to next column'
PRINT @Tab + @Tab + @Tab + 'grd.Col = grd.Col + 1'
PRINT @Tab + @Tab + 'End If'
PRINT @Tab + 'End If'
PRINT @Tab + '''...grdEnhancement'
PRINT 'End Sub'

PRINT ''


PRINT 'Private Sub grd_KeyUp(KeyCode As Integer, Shift As Integer)'


PRINT @Tab + 'If KeyCode = vbKeyInsert Or KeyCode = vbKeyF7 Then'

PRINT @Tab + @Tab + 'grd.Update'
PRINT @Tab + @Tab + 'grd.AddItem NewGuid'
PRINT @Tab + @Tab + 'grd.MoveLast'


DECLARE @Lookups VARCHAR(8000)

set @Lookups = ''
select
TOP 1 @Lookups = 'txt' + c.name + '.DoClickButton grd'
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableDetailName)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableDetailName, i.indid, 1) or
c.name = index_col (@TableDetailName, i.indid, 2) or
c.name = index_col (@TableDetailName, i.indid, 3) or
c.name = index_col (@TableDetailName, i.indid, 4) or
c.name = index_col (@TableDetailName, i.indid, 5) or
c.name = index_col (@TableDetailName, i.indid, 6) or
c.name = index_col (@TableDetailName, i.indid, 7) or
c.name = index_col (@TableDetailName, i.indid, 8) or
c.name = index_col (@TableDetailName, i.indid, 9) or
c.name = index_col (@TableDetailName, i.indid, 10) or
c.name = index_col (@TableDetailName, i.indid, 11) or
c.name = index_col (@TableDetailName, i.indid, 12) or
c.name = index_col (@TableDetailName, i.indid, 13) or
c.name = index_col (@TableDetailName, i.indid, 14) or
c.name = index_col (@TableDetailName, i.indid, 15) or
c.name = index_col (@TableDetailName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id


AND C.Name NOT IN
(

select
C.Name
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
) --and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id



)

order by c.colid



PRINT @Tab + @Tab + @Lookups

PRINT @Tab + 'ElseIf KeyCode = vbKeyDelete And Shift = vbAltMask Then'

PRINT @Tab + @Tab + '''grdEnhancement... don''t delete this comment'
PRINT @Tab + @Tab + 'Dim PrevCol As Integer'
PRINT @Tab + @Tab + 'PrevCol = grd.Col'
PRINT @Tab + @Tab + '''...grdEnhancement'


PRINT ''

PRINT @Tab + @Tab + 'Dim BM'
PRINT @Tab + @Tab + 'If grd.SelBookmarks.Count > 0 Then'
PRINT @Tab + @Tab + @Tab + 'For Each BM In grd.SelBookmarks'
PRINT @Tab + @Tab + @Tab + @Tab + 'If grd.Columns("RecID").CellValue(BM) <> "" Then'
PRINT @Tab + @Tab + @Tab + @Tab + @Tab + 'm_rsDeleted.AddNew'
PRINT @Tab + @Tab + @Tab + @Tab + @Tab + 'm_rsDeleted.Fields("RecId").Value = grd.Columns("RecID").CellValue(BM)'
PRINT @Tab + @Tab + @Tab + @Tab + @Tab + 'm_rsDeleted.Update'
PRINT @Tab + @Tab + @Tab + @Tab + 'End If'
PRINT @Tab + @Tab + @Tab + 'Next BM'

PRINT @Tab + @Tab + 'Else'
PRINT @Tab + @Tab + @Tab + 'If grd.Columns("RecID").CellValue(BM) <> "" Then'
PRINT @Tab + @Tab + @Tab + @Tab + 'm_rsDeleted.AddNew'
PRINT @Tab + @Tab + @Tab + @Tab + 'm_rsDeleted.Fields("RecId").Value = grd.Columns("RecID").CellValue(grd.Bookmark)'
PRINT @Tab + @Tab + @Tab + @Tab + 'm_rsDeleted.Update'
PRINT @Tab + @Tab + @Tab + 'End If'
PRINT @Tab + @Tab + @Tab + 'grd.SelBookmarks.Add grd.AddItemRowIndex(grd.Bookmark)'
PRINT @Tab + @Tab + 'End If'

PRINT @Tab + @Tab + 'grd.DeleteSelected'

PRINT ''

PRINT @Tab + @Tab + '''grdEnhancement... don''t delete this comment'
PRINT @Tab + @Tab + 'grd.Col = PrevCol'
PRINT @Tab + @Tab + '''...grdEnhancement'

PRINT @Tab + 'End If'

PRINT ''

PRINT @Tab + '''grdEnhancement... don''t delete this comment'
PRINT @Tab + 'If KeyCode = vbKeyReturn Then'
PRINT @Tab + @Tab + 'grd.Update'
PRINT @Tab + 'End If'
PRINT @Tab + '''...grdEnhancement'



PRINT 'End Sub'

PRINT ''

PRINT 'Private Sub grd_RowColChange(ByVal LastRow As Variant, ByVal LastCol As Integer)'
PRINT ''
PRINT @Tab + '''grdEnhancement... don''t delete this comment'
PRINT @Tab + 'If grd.Col < 0 And LastCol >= 0 Then'
PRINT @Tab + @Tab + 'grd.Col = LastCol'
PRINT @Tab + 'End If'
PRINT @Tab + 'grd.ActiveCell.SelLength = Len(grd.ActiveCell.Text)'
PRINT @Tab + '''...grdEnhancement'
PRINT 'End Sub'

PRINT ''

PRINT 'Private Sub grd_UpdateError(ByVal ColIndex As Integer, Text As String, ErrCode As Integer, ErrString As String, Cancel As Integer)'
PRINT @Tab + '''grdEnhancement... don''t delete this comment'
PRINT @Tab + 'Cancel = 1'
PRINT @Tab + '''...grdEnhancement'
PRINT 'End Sub'

PRINT ''

PRINT 'Private Sub grd_GotFocus()'
PRINT @Tab + '''grdEnhancement... don''t delete this comment'
PRINT @Tab + 'grd.ForeColor = m_grdGotFocusColor'
PRINT @Tab + '''...grdEnhancement'
PRINT 'End Sub'

PRINT ''

PRINT 'Private Sub grd_LostFocus()'
PRINT @Tab + '''grdEnhancement... don''t delete this comment'
PRINT @Tab + 'grd.ForeColor = m_grdGotFocusColor'
PRINT @Tab + '''...grdEnhancement'
PRINT 'End Sub'

PRINT ''


PRINT 'Private Sub grd_AfterDelete(RtnDispErrMsg As Integer)'
PRINT @Tab + 'If grd.AddItemRowIndex(grd.Bookmark) >= grd.Rows Then'
PRINT @Tab + @Tab + 'grd.Bookmark = grd.AddItemBookmark(grd.Rows - 1)'
PRINT @Tab + 'End If'
PRINT 'End Sub'

PRINT ''

PRINT '''grid Lookups...'

-- pick all primary keys found in details, but whose field is not in header
SET @C = CURSOR FOR
SELECT C.Name, C.XType, dt.VbType, ReferencedTableName = rt.name, c.length
FROM syscolumns AS C
INNER JOIN systypes AS ST ON C.xtype = st.xtype
INNER JOIN CodeGen_DataTypes AS dt ON dt.sqltype = st.name
INNER JOIN sysforeignkeys AS sfk ON sfk.fkeyid = c.id AND sfk.fkey = c.colid
INNER JOIN sysobjects AS rt ON rt.id = sfk.rkeyid
INNER JOIN sysindexes AS i ON i.id = c.id
WHERE c.id = object_id(@TableDetailName)
AND C.iscomputed = 0
AND CHARINDEX('_', c.Name) = 0

AND C.Name NOT IN (SELECT GeographicCode FROM CodeGen_Geographic)

--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id


AND C.Name NOT IN
(

select
C.Name
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
) --and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id


)

ORDER BY c.colid

OPEN @C

FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_ReferencedTableName, @C_length
WHILE @@FETCH_STATUS = 0 BEGIN


-- PRINT @C_ReferencedTableName + ':' + @C_Name

PRINT 'Private Sub txt' + @C_Name + '_Dropdown(UseDefault As Boolean, RS As ADODB.Recordset, RecordsetPositioner As String)'

PRINT @TryBlockBegin
PRINT @Tab + 'Dim E As String'
PRINT @Tab + 'Set RS = Services.' + @C_ReferencedTableName + '_Lookup(E, "")'

PRINT @TryBlockEnd

PRINT @CatchBlockBegin

PRINT dbo.CodeGenFe_CatchBlockEnd('txt' + @C_Name + '_Dropdown')

PRINT @FinallyBlockBegin

PRINT @FinallyBlockEnd

PRINT 'End Sub'

PRINT ''



PRINT 'Private Sub txt' + @C_Name + '_GotoRecord(RS As ADODB.Recordset)'

PRINT @TryBlockBegin

PRINT @Tab + 'grd.Columns("' + @C_Name + '").Value = RS.Fields("' + @C_Name + '").Value'
PRINT @Tab + 'grd.Update'

PRINT ''

print @Tab + '''grdEnhancement... don''t delete this comment'
PRINT @Tab + 'grd.Col = grd.Columns("' + @C_Name + '").Position + 1'
PRINT @Tab + '''...grdEnhancement'


PRINT @TryBlockEnd

PRINT @CatchBlockBegin

PRINT dbo.CodeGenFe_CatchBlockEnd('txt' + @C_Name + '_GotoRecord')

PRINT @FinallyBlockBegin

PRINT @FinallyBlockEnd

PRINT 'End Sub'


PRINT ''

FETCH NEXT FROM @C INTO @C_Name, @C_XType, @C_VbType, @C_ReferencedTableName, @C_length
END



CLOSE @C

DEALLOCATE @C


PRINT '''...grid Lookups'


PRINT ''

PRINT '''...Details'










GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
























CREATE PROCEDURE CodeGenMt_OneTableNoAutoId
@TransactName VARCHAR(100),
@TableName VARCHAR(100)
AS


IF object_id(@TableName) IS NULL BEGIN
PRINT 'Table ' + @TableName + ' does not exists'
RETURN
END




PRINT '''' + @TableName + ' add/edit/delete...'

PRINT ''

DECLARE @Tab VARCHAR(4)

SET @Tab = SPACE(4)



DECLARE @TryBlockBegin VARCHAR(8000)

SET @TryBlockBegin = @Tab + '''Try{' + CHAR(13) + @Tab + 'On Error GoTo goCatchError' + CHAR(13)

DECLARE @TryBlockEnd VARCHAR(8000)

SET @TryBlockEnd = CHAR(13) + @Tab + 'GoTo goFinally' + CHAR(13) + @Tab + '''}' + CHAR(13)


DECLARE @CatchBlockBegin VARCHAR(8000)

SET @CatchBlockBegin= @Tab + '''CatchError{' + CHAR(13) + 'goCatchError:' + CHAR(13) + CHAR(13) + char(13)

+ @Tab + 'Screen.MousePointer = vbDefault'






DECLARE @FinallyBlockBegin VARCHAR(8000)

SET @FinallyBlockBegin = @Tab + '''Finally{' + CHAR(13) + 'goFinally:' + CHAR(13) + CHAR(13)

DECLARE @FinallyBlockEnd VARCHAR(8000)

SET @FinallyBlockEnd = @Tab + '''}'



DECLARE @PkFields VARCHAR(8000)



SET @PkFields = NULL
select
@PkFields = coalesce(
@PkFields + ', ByVal ' + c.Name + ' As String'
,'ByVal ' + C.Name + ' As String' )
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@tablename)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@tablename, i.indid, c1.colid)
and (c.name = index_col (@tablename, i.indid, 1) or
c.name = index_col (@tablename, i.indid, 2) or
c.name = index_col (@tablename, i.indid, 3) or
c.name = index_col (@tablename, i.indid, 4) or
c.name = index_col (@tablename, i.indid, 5) or
c.name = index_col (@tablename, i.indid, 6) or
c.name = index_col (@tablename, i.indid, 7) or
c.name = index_col (@tablename, i.indid, 8) or
c.name = index_col (@tablename, i.indid, 9) or
c.name = index_col (@tablename, i.indid, 10) or
c.name = index_col (@tablename, i.indid, 11) or
c.name = index_col (@tablename, i.indid, 12) or
c.name = index_col (@tablename, i.indid, 13) or
c.name = index_col (@tablename, i.indid, 14) or
c.name = index_col (@tablename, i.indid, 15) or
c.name = index_col (@tablename, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid




declare @PkCondition varchar(8000)

set @PkCondition = NULL


select
@PkCondition = coalesce(
@PkCondition + ' AND ' + c.Name + ' = ''" & Enquote(' + c.Name + ') & "''"'
,c.Name + ' = ''" & Enquote(' + c.Name + ') & "''"')
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@tablename)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@tablename, i.indid, c1.colid)
and (c.name = index_col (@tablename, i.indid, 1) or
c.name = index_col (@tablename, i.indid, 2) or
c.name = index_col (@tablename, i.indid, 3) or
c.name = index_col (@tablename, i.indid, 4) or
c.name = index_col (@tablename, i.indid, 5) or
c.name = index_col (@tablename, i.indid, 6) or
c.name = index_col (@tablename, i.indid, 7) or
c.name = index_col (@tablename, i.indid, 8) or
c.name = index_col (@tablename, i.indid, 9) or
c.name = index_col (@tablename, i.indid, 10) or
c.name = index_col (@tablename, i.indid, 11) or
c.name = index_col (@tablename, i.indid, 12) or
c.name = index_col (@tablename, i.indid, 13) or
c.name = index_col (@tablename, i.indid, 14) or
c.name = index_col (@tablename, i.indid, 15) or
c.name = index_col (@tablename, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid





---------------------------

DECLARE @S VARCHAR(8000)


SET @S =
'Public Sub ' + @TransactName + '_Save(ByRef ReturnError As String, '
+ 'ByVal AccessKey As String, '
+ 'ByVal IsExisting As Boolean, '


SET @S = @S + @PkFields + ', ByVal RsSrc AS ADODB.Recordset)'


PRINT @S





/*

' Ver 1
If IsOldRecord Then
Set RsItem = m_Database.NewRsOpen("SELECT * FROM Item WHERE ItemCode='" & Enquote(Rs.Fields("ItemCode").Value) & "'", adOpenStatic, adLockOptimistic)
Else
Set RsItem = m_Database.NewRsOpen("SELECT * FROM Item WHERE 1=0", adOpenStatic, adLockOptimistic)
RsItem.AddNew
RsItem.Fields("ItemCode").Value = Rs.Fields("ItemCode").Value
End If



'Ver 2
Set RsItem = m_Database.NewRsOpen("SELECT * FROM Item WHERE ItemCode='" & Enquote(Rs.Fields("ItemCode").Value) & "'", adOpenStatic, adLockOptimistic)

If IsOldRecord Then
If RsItem.RecordCount = 0 Then
Err.Raise 777,"", "Record already deleted by other user before you have even saved this record"
End If
Else
If RsItem.RecordCount > 0 Then
err.raise 777, "", "Item code already exist, please change itemcode"
Else
RsItem.AddNew
RsItem.Fields("ItemCode").Value = Rs.Fields("ItemCode").Value
End If
End If




*/





PRINT @TryBlockBegin


PRINT @Tab + 'm_Database.BeginTrans'
PRINT ''
PRINT @Tab + 'Dim RsDst AS ADODB.Recordset'
PRINT ''


DECLARE @FieldComma VARCHAR(8000)

SET @FieldComma = NULL
SELECT @FieldComma = COALESCE(@FieldComma + ',' + Name, Name) FROM syscolumns WHERE id = object_id(@TableName) AND
iscomputed = 0
AND
(
PATINDEX('%_QTY', Name) = 0
AND PATINDEX('%_COST', Name) = 0
AND PATINDEX('%_PRICE', Name) = 0)
ORDER BY colid


SET @s = @Tab + 'Set RsDst = m_Database.NewRsOpen("SELECT ' + @FieldComma + ' FROM ' + @TableName + ' WHERE ' + @PkCondition + ', adOpenStatic, adLockOptimistic)'


print @s


print ''

PRINT @Tab + 'If IsExisting Then'
PRINT @Tab + @Tab + 'If RsDst.RecordCount = 0 Then'
PRINT @Tab + @Tab + @Tab + 'Err.Raise 777, "", "' + @TransactName + ' already deleted by other user before you have even saved"'
PRINT @Tab + @Tab + 'End If'
PRINT @Tab + 'Else'
PRINT @Tab + @Tab + 'If RsDst.RecordCount > 0 Then'
PRINT @Tab + @Tab + @Tab + 'Err.Raise 777, "", "' + @TransactName + ' already exist"'
PRINT @Tab + @Tab + 'Else'
PRINT @Tab + @Tab + @Tab + 'RsDst.AddNew'

SET @S = NULL
select
@S = coalesce(
@S + CHAR(13) + @Tab + @Tab + @Tab + 'RsDst.Fields("' + c.Name + '").Value = ' + c.Name
, @Tab + @Tab + @Tab + 'RsDst.Fields("' + c.Name + '").Value = ' + c.Name )
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@tablename)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@tablename, i.indid, c1.colid)
and (c.name = index_col (@tablename, i.indid, 1) or
c.name = index_col (@tablename, i.indid, 2) or
c.name = index_col (@tablename, i.indid, 3) or
c.name = index_col (@tablename, i.indid, 4) or
c.name = index_col (@tablename, i.indid, 5) or
c.name = index_col (@tablename, i.indid, 6) or
c.name = index_col (@tablename, i.indid, 7) or
c.name = index_col (@tablename, i.indid, 8) or
c.name = index_col (@tablename, i.indid, 9) or
c.name = index_col (@tablename, i.indid, 10) or
c.name = index_col (@tablename, i.indid, 11) or
c.name = index_col (@tablename, i.indid, 12) or
c.name = index_col (@tablename, i.indid, 13) or
c.name = index_col (@tablename, i.indid, 14) or
c.name = index_col (@tablename, i.indid, 15) or
c.name = index_col (@tablename, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid

PRINT @S


PRINT @Tab + @Tab + 'End If'
PRINT @Tab + 'End If'


PRINT ''


DECLARE @c CURSOR

SET @C = CURSOR FOR SELECT Name FROM syscolumns WHERE id = object_id(@TableName) AND
iscomputed = 0
AND
(
PATINDEX('%_QTY', Name) = 0
AND PATINDEX('%_COST', Name) = 0
AND PATINDEX('%_PRICE', Name) = 0)
ORDER BY colid

OPEN @C


DECLARE @C_Name AS VARCHAR(100)
FETCH NEXT FROM @C INTO @C_Name
WHILE @@FETCH_STATUS = 0 BEGIN


IF EXISTS(


select
*
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@tablename)
AND C.NAME = @C_name
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@tablename, i.indid, c1.colid)
and (c.name = index_col (@tablename, i.indid, 1) or
c.name = index_col (@tablename, i.indid, 2) or
c.name = index_col (@tablename, i.indid, 3) or
c.name = index_col (@tablename, i.indid, 4) or
c.name = index_col (@tablename, i.indid, 5) or
c.name = index_col (@tablename, i.indid, 6) or
c.name = index_col (@tablename, i.indid, 7) or
c.name = index_col (@tablename, i.indid, 8) or
c.name = index_col (@tablename, i.indid, 9) or
c.name = index_col (@tablename, i.indid, 10) or
c.name = index_col (@tablename, i.indid, 11) or
c.name = index_col (@tablename, i.indid, 12) or
c.name = index_col (@tablename, i.indid, 13) or
c.name = index_col (@tablename, i.indid, 14) or
c.name = index_col (@tablename, i.indid, 15) or
c.name = index_col (@tablename, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id



)
BEGIN

GOTO goContinue

END






SET @S = @C_Name

PRINT @Tab + 'RsDst.Fields("' + @S + '").Value = RsSrc.Fields("' + @S + '").Value'


goContinue:
FETCH NEXT FROM @C INTO @C_Name
END


CLOSE @C

DEALLOCATE @C

PRINT @Tab + 'RsDst.Update'


PRINT ''

PRINT @Tab + 'm_Database.CommitTrans'

PRINT @TryBlockEnd


PRINT @CatchBlockBegin



PRINT @Tab + 'm_Database.RollbackTrans'




PRINT dbo.CodeGenMt_CatchBlockEnd (@TransactName + '_Save')


PRINT @FinallyBlockBegin




PRINT @FinallyBlockEnd

PRINT 'End Sub'


PRINT ''




-------------------------------
PRINT 'Public Function ' + @TransactName + '_IsExisting(ByRef ReturnError As String, ByVal AccessKey As String, ' + @PkFields + ') As Boolean'


PRINT @TryBlockBegin

SET @S = @Tab + @TransactName + '_IsExisting = m_Database.NewRsOpen("SELECT COUNT(*) As Cnt FROM ' + @TableName + ' WHERE ' + @PkCondition + ').Fields("Cnt").Value = 1'
PRINT @S


PRINT @TryBlockEnd

PRINT @CatchBlockBegin

PRINT dbo.CodeGenMt_CatchBlockEnd (@TransactName + '_IsExisting')


PRINT @FinallyBlockBegin

PRINT @FinallyBlockEnd

PRINT 'End Function'


--------------------------------------------
PRINT ''
PRINT 'Public Sub ' + @TransactName + '_Open(ByRef ReturnError As String, ByVal AccessKey As String, ' + @PkFields + ', ByRef RsReturn As ADODB.Recordset)'


PRINT @TryBlockBegin

PRINT ''

SET @s = @Tab + 'Set RsReturn = m_Database.NewRsOpen("SELECT ' + @FieldComma + ' FROM ' + @TableName + ' WHERE ' + @PkCondition + ')'

print @s


PRINT @TryBlockEnd

PRINT @CatchBlockBegin


PRINT dbo.CodeGenMt_CatchBlockEnd (@TransactName + '_Open')


PRINT @FinallyBlockBegin

PRINT @FinallyBlockEnd


PRINT 'End Sub'

-------------------------------------------------------------------------
PRINT ''
PRINT 'Public Function ' + @TransactName + '_Browse(ByRef ReturnError As String, ByVal AccessKey As String) As ADODB.Recordset'

PRINT @TryBlockBegin


SET @S = NULL
SELECT @S = COALESCE(@S + ',' + Name, Name) FROM syscolumns WHERE id = object_id(@TableName) AND
iscomputed = 0
AND
(
PATINDEX('%_QTY', Name) = 0
AND PATINDEX('%_COST', Name) = 0
AND PATINDEX('%_PRICE', Name) = 0)
AND colid BETWEEN 1 AND 3
ORDER BY colid


SET @s = @Tab + 'Set ' + @TransactName + '_Browse = m_Database.NewRsOpen("SELECT ' + @s + ' FROM ' + @TableName + '")'


PRINT ''

print @s


PRINT ''

PRINT @TryBlockEnd

PRINT @CatchBlockBegin

PRINT dbo.CodeGenMt_CatchBlockEnd (@TransactName + '_Browse')

PRINT @FinallyBlockBegin

PRINT @FinallyBlockEnd


PRINT 'End Function'


-------------------------------------------------------------------------





-------------------------------------------------------------------------
PRINT ''
PRINT 'Public Function ' + @TransactName + '_Lookup(ByRef ReturnError As String, ByVal AccessKey As String) As ADODB.Recordset'

PRINT @TryBlockBegin


SET @S = NULL
SELECT @S = COALESCE(@S + ',' + Name, Name) FROM syscolumns WHERE id = object_id(@TableName) AND
iscomputed = 0
AND
(
PATINDEX('%_QTY', Name) = 0
AND PATINDEX('%_COST', Name) = 0
AND PATINDEX('%_PRICE', Name) = 0)
AND colid BETWEEN 1 AND 3
ORDER BY colid


SET @s = @Tab + 'Set ' + @TransactName + '_Lookup = m_Database.NewRsOpen("SELECT ' + @s + ' FROM ' + @TableName + '")'


PRINT ''

print @s


PRINT ''

PRINT @TryBlockEnd

PRINT @CatchBlockBegin

PRINT dbo.CodeGenMt_CatchBlockEnd (@TransactName + '_Lookup')

PRINT @FinallyBlockBegin

PRINT @FinallyBlockEnd


PRINT 'End Function'


-------------------------------------------------------------------------



PRINT ''

PRINT 'Public Sub ' + @TransactName + '_Delete(ByRef ReturnError As String, ByVal AccessKey As String, ' + @PkFields + ')'

PRINT @TryBlockBegin

PRINT @Tab + 'm_Database.BeginTrans'
print ''

SET @s = @Tab + 'Call m_Database.NewRsOpen("DELETE FROM ' + @TableName + ' WHERE ' + @PkCondition + ')'

PRINT @s

PRINT @Tab + 'm_Database.CommitTrans'

PRINT @TryBlockEnd

PRINT @CatchBlockBegin

PRINT @Tab + 'm_Database.RollbackTrans'

PRINT dbo.CodeGenMt_CatchBlockEnd (@TransactName + '_Delete')

PRINT @FinallyBlockBegin

PRINT @FinallyBlockEnd




PRINT 'End Sub'

PRINT ''

PRINT '''...' + @TransactName + ' add/edit/delete'













GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO



























CREATE PROCEDURE CodeGenMt_TwoTableNoAutoId
@TableTransactName VARCHAR(100),
@TableHeaderName VARCHAR(100),
@TableDetailName VARCHAR(100)
AS


IF object_id(@TableHeaderName) IS NULL BEGIN
PRINT 'Table ' + @TableHeaderName + ' does not exists'
RETURN
END


IF object_id(@TableDetailName) IS NULL BEGIN
PRINT 'Table ' + @TableDetailName + ' does not exists'
RETURN
END



PRINT '''' + @TableTransactName + ' add/edit/delete...'

PRINT ''

DECLARE @Tab VARCHAR(4)

SET @Tab = SPACE(4)



DECLARE @TryBlockBegin VARCHAR(8000)

SET @TryBlockBegin = @Tab + '''Try{' + CHAR(13) + @Tab + 'On Error GoTo goCatchError' + CHAR(13)

DECLARE @TryBlockEnd VARCHAR(8000)

SET @TryBlockEnd = CHAR(13) + @Tab + 'GoTo goFinally' + CHAR(13) + @Tab + '''}' + CHAR(13)


DECLARE @CatchBlockBegin VARCHAR(8000)

SET @CatchBlockBegin= @Tab + '''CatchError{' + CHAR(13) + 'goCatchError:' + CHAR(13) + CHAR(13) + char(13)

+ @Tab + 'Screen.MousePointer = vbDefault'






DECLARE @FinallyBlockBegin VARCHAR(8000)

SET @FinallyBlockBegin = @Tab + '''Finally{' + CHAR(13) + 'goFinally:' + CHAR(13) + CHAR(13)

DECLARE @FinallyBlockEnd VARCHAR(8000)

SET @FinallyBlockEnd = @Tab + '''}'



DECLARE @PkFields VARCHAR(8000)



SET @PkFields = NULL
select
@PkFields = coalesce(
@PkFields + ', ByVal ' + c.Name + ' As String'
,'ByVal ' + C.Name + ' As String' )
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid




declare @PkCondition varchar(8000)

set @PkCondition = NULL


select
@PkCondition = coalesce(
@PkCondition + ' AND ' + c.Name + ' = ''" & Enquote(' + c.Name + ') & "''"'
,c.Name + ' = ''" & Enquote(' + c.Name + ') & "''"')
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid





---------------------------

DECLARE @S VARCHAR(8000)


SET @S =
'Public Sub ' + @TableTransactName + '_Save(ByRef ReturnError As String, '
+ 'ByVal AccessKey As String, '
+ 'ByVal IsExisting As Boolean, '

SET @S = @S + @PkFields
+ ', ByVal RsHeaderSrc AS ADODB.Recordset ' +
+ ', ByVal RsDetailSrc As ADODB.Recordset ' +
+ ', ByVal RsDetailDel As ADODB.Recordset)'


PRINT @S





/*

' Ver 1
If IsOldRecord Then
Set RsItem = m_Database.NewRsOpen("SELECT * FROM Item WHERE ItemCode='" & Enquote(Rs.Fields("ItemCode").Value) & "'", adOpenStatic, adLockOptimistic)
Else
Set RsItem = m_Database.NewRsOpen("SELECT * FROM Item WHERE 1=0", adOpenStatic, adLockOptimistic)
RsItem.AddNew
RsItem.Fields("ItemCode").Value = Rs.Fields("ItemCode").Value
End If



'Ver 2
Set RsItem = m_Database.NewRsOpen("SELECT * FROM Item WHERE ItemCode='" & Enquote(Rs.Fields("ItemCode").Value) & "'", adOpenStatic, adLockOptimistic)

If IsOldRecord Then
If RsItem.RecordCount = 0 Then
Err.Raise 777,"", "Record already deleted by other user before you have even saved this record"
End If
Else
If RsItem.RecordCount > 0 Then
err.raise 777, "", "Item code already exist, please change itemcode"
Else
RsItem.AddNew
RsItem.Fields("ItemCode").Value = Rs.Fields("ItemCode").Value
End If
End If




*/





PRINT @TryBlockBegin


PRINT @Tab + 'm_Database.BeginTrans'
PRINT ''
PRINT @Tab + 'Dim RsHeaderDst AS ADODB.Recordset'
PRINT ''


DECLARE @FieldComma VARCHAR(8000)

SET @FieldComma = NULL
SELECT @FieldComma = COALESCE(@FieldComma + ',' + Name, Name) FROM syscolumns WHERE id = object_id(@TableHeaderName) AND
iscomputed = 0
AND
(
CHARINDEX('_', Name) = 0
)
ORDER BY colid




DECLARE @FieldCommaDetail VARCHAR(8000)

SET @FieldCommaDetail = NULL
SELECT @FieldCommaDetail = COALESCE(@FieldCommaDetail + ',' + Name, Name) FROM syscolumns as detailcol WHERE id = object_id(@TableDetailName) AND
iscomputed = 0
AND
(
CHARINDEX('_', Name) = 0
)

AND NOT EXISTS
(
select
*
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
and c.name = detailcol.name
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id

)
ORDER BY colid




SET @s = @Tab + 'Set RsHeaderDst = m_Database.NewRsOpen("SELECT ' + @FieldComma + ' FROM ' + @TableHeaderName + ' WHERE ' + @PkCondition + ', adOpenStatic, adLockOptimistic)'


print @s


print ''

PRINT @Tab + 'If IsExisting Then'
PRINT @Tab + @Tab + 'If RsHeaderDst.RecordCount = 0 Then'
PRINT @Tab + @Tab + @Tab + 'Err.Raise 777, "", "' + @TableTransactName + ' already deleted by other user before you have even saved"'
PRINT @Tab + @Tab + 'End If'
PRINT @Tab + 'Else'
PRINT @Tab + @Tab + 'If RsHeaderDst.RecordCount > 0 Then'
PRINT @Tab + @Tab + @Tab + 'Err.Raise 777, "", "' + @TableTransactName + ' already exist"'
PRINT @Tab + @Tab + 'Else'
PRINT @Tab + @Tab + @Tab + 'RsHeaderDst.AddNew'

SET @S = NULL
select
@S = coalesce(
@S + CHAR(13) + @Tab + @Tab + @Tab + 'RsHeaderDst.Fields("' + c.Name + '").Value = ' + c.Name
, @Tab + @Tab + @Tab + 'RsHeaderDst.Fields("' + c.Name + '").Value = ' + c.Name )
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid

PRINT @S


PRINT @Tab + @Tab + 'End If'
PRINT @Tab + 'End If'


PRINT ''


DECLARE @c CURSOR

SET @C = CURSOR FOR SELECT Name FROM syscolumns WHERE id = object_id(@TableHeaderName) AND
iscomputed = 0
AND
(
CHARINDEX('_', Name) = 0
)
ORDER BY colid

OPEN @C


DECLARE @C_Name AS VARCHAR(100)
FETCH NEXT FROM @C INTO @C_Name
WHILE @@FETCH_STATUS = 0 BEGIN


IF EXISTS(


select
*
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
AND C.NAME = @C_name
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id



)
BEGIN

GOTO goContinue

END






SET @S = @C_Name

PRINT @Tab + 'RsHeaderDst.Fields("' + @S + '").Value = RsHeaderSrc.Fields("' + @S + '").Value'


goContinue:
FETCH NEXT FROM @C INTO @C_Name
END


CLOSE @C

DEALLOCATE @C

PRINT @Tab + 'RsHeaderDst.Update'



--------------
-- detail here...



PRINT ''
PRINT ''

PRINT @Tab + 'If RsDetailDel.RecordCount > 0 Then'
PRINT @Tab + @Tab + 'RsDetailDel.MoveFirst'
PRINT @Tab + @Tab + 'Do Until RsDetailDel.EOF'
PRINT @Tab + @Tab + @Tab + 'Call m_Database.NewRsOpen("DELETE FROM ' + @TableDetailName + ' WHERE RecID = ''" & Enquote(RsDetailDel.Fields("RecID").Value) & "''")'
PRINT @Tab + @Tab + @Tab + 'RsDetailDel.MoveNext'
PRINT @Tab + @Tab + 'Loop'
PRINT @Tab + 'End If'


PRINT ''

PRINT @Tab + 'Dim RsDetailDst AS ADODB.Recordset'

PRINT ''

DECLARE @CDetail CURSOR

SET @CDetail = CURSOR FOR SELECT Name FROM syscolumns WHERE id = object_id(@TableDetailName) AND
iscomputed = 0
AND
(
CHARINDEX('_', Name) = 0
)
ORDER BY colid

OPEN @CDetail


DECLARE @CD_Name AS VARCHAR(100)

SET @FieldCommaDetail = NULL
SELECT @FieldCommaDetail = COALESCE(@FieldCommaDetail + ',' + Name, Name) FROM syscolumns as detailcol WHERE id = object_id(@TableDetailName) AND
iscomputed = 0
AND
(
CHARINDEX('_', Name) = 0
)
ORDER BY colid




PRINT @Tab + 'If RsDetailSrc.RecordCount > 0 Then'
PRINT @Tab + @Tab + 'RsDetailSrc.MoveFirst'
PRINT @Tab + @Tab + 'Do Until RsDetailSrc.EOF'
PRINT @Tab + @Tab + @Tab + 'Set RsDetailDst = m_Database.NewRsOpen("SELECT ' + @FieldCommaDetail + ' FROM ' + @TableDetailName + ' WHERE RecID=''" & Enquote(RsDetailSrc.Fields("RecId").Value) & "''", adOpenStatic, adLockOptimistic)'
PRINT @Tab + @Tab + @Tab + 'If RsDetailDst.EOF Then'
PRINT @Tab + @Tab + @Tab + @Tab + 'RsDetailDst.AddNew'
PRINT @Tab + @Tab + @Tab + @Tab + 'RsDetailDst.Fields("RecID").Value = RsDetailSrc.Fields("RecID").Value'


SET @S = NULL
select
@S = coalesce(
@S + CHAR(13) + @Tab + @Tab + @Tab + @Tab + 'RsDetailDst.Fields("' + c.Name + '").Value = ' + c.Name
, @Tab + @Tab + @Tab + @Tab + 'RsDetailDst.Fields("' + c.Name + '").Value = ' + c.Name )
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id
order by c.colid


PRINT @S


PRINT @Tab + @Tab + @Tab + 'End If'

PRINT ''



FETCH NEXT FROM @CDetail INTO @CD_Name
WHILE @@FETCH_STATUS = 0 BEGIN


IF EXISTS(


select
*
from
sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
where
o.id = object_id(@TableHeaderName)
AND C.name = @CD_Name
and o.id = c.id
and o.id = i.id
and (i.status & 0x800) = 0x800
--and c.name = index_col (@TableHeaderName, i.indid, c1.colid)
and (c.name = index_col (@TableHeaderName, i.indid, 1) or
c.name = index_col (@TableHeaderName, i.indid, 2) or
c.name = index_col (@TableHeaderName, i.indid, 3) or
c.name = index_col (@TableHeaderName, i.indid, 4) or
c.name = index_col (@TableHeaderName, i.indid, 5) or
c.name = index_col (@TableHeaderName, i.indid, 6) or
c.name = index_col (@TableHeaderName, i.indid, 7) or
c.name = index_col (@TableHeaderName, i.indid, 8) or
c.name = index_col (@TableHeaderName, i.indid, 9) or
c.name = index_col (@TableHeaderName, i.indid, 10) or
c.name = index_col (@TableHeaderName, i.indid, 11) or
c.name = index_col (@TableHeaderName, i.indid, 12) or
c.name = index_col (@TableHeaderName, i.indid, 13) or
c.name = index_col (@TableHeaderName, i.indid, 14) or
c.name = index_col (@TableHeaderName, i.indid, 15) or
c.name = index_col (@TableHeaderName, i.indid, 16)
)
--and c1.colid <= i.keycnt /* create rows from 1 to keycnt */
--and c1.id = @table_id



)
BEGIN
GOTO goContinueSaveDetail
END


IF (@CD_Name = 'RecId') BEGIN
GOTO goContinueSaveDetail
END


PRINT @Tab + @Tab + @Tab + 'RsDetailDst.Fields("' + @CD_Name + '").Value = RsDetailSrc.Fields("' + @CD_Name + '").Value'


goContinueSaveDetail:
FETCH NEXT FROM @CDetail INTO @CD_Name
END



PRINT @Tab + @Tab + @Tab + 'RsDetailDst.Update'
PRINT @Tab + @Tab + @Tab + 'RsDetailSrc.MoveNext'
PRINT @Tab + @Tab + 'Loop'
PRINT @Tab + 'End If'

CLOSE @CDetail


-- ...detail here
---------------------

PRINT ''

PRINT @Tab + 'm_Database.CommitTrans'

PRINT @TryBlockEnd


PRINT @CatchBlockBegin



PRINT @Tab + 'm_Database.RollbackTrans'




PRINT dbo.CodeGenMt_CatchBlockEnd (@TableTransactName + '_Save')


PRINT @FinallyBlockBegin




PRINT @FinallyBlockEnd

PRINT 'End Sub'


PRINT ''




-------------------------------
PRINT 'Public Function ' + @TableTransactName + '_IsExisting(ByRef ReturnError As String, ByVal AccessKey As String, ' + @PkFields + ') As Boolean'


PRINT @TryBlockBegin

SET @S = @Tab + @TableTransactName + '_IsExisting = m_Database.NewRsOpen("SELECT COUNT(*) As Cnt FROM ' + @TableHeaderName + ' WHERE ' + @PkCondition + ').Fields("Cnt").Value = 1'
PRINT @S


PRINT @TryBlockEnd

PRINT @CatchBlockBegin

PRINT dbo.CodeGenMt_CatchBlockEnd (@TableTransactName + '_IsExisting')


PRINT @FinallyBlockBegin

PRINT @FinallyBlockEnd

PRINT 'End Function'


--------------------------------------------
PRINT ''
PRINT 'Public Sub ' + @TableTransactName + '_Open(ByRef ReturnError As String, ByVal AccessKey As String, ' + @PkFields + ', ByRef RsHeaderReturn As ADODB.Recordset, ByRef RsDetailReturn As ADODB.Recordset)'


PRINT @TryBlockBegin

PRINT ''

SET @s = @Tab + 'Set RsHeaderReturn = m_Database.NewRsOpen("SELECT ' + @FieldComma + ' FROM ' + @TableHeaderName + ' WHERE ' + @PkCondition + ')'

print @s


SET @S = @Tab + 'Set RsDetailReturn = m_Database.NewRsOpen("SELECT ' + @FieldCommaDetail + ' FROM ' + @TableDetailName + ' WHERE ' + @PkCondition + ')'

print @s

PRINT @TryBlockEnd

PRINT @CatchBlockBegin


PRINT dbo.CodeGenMt_CatchBlockEnd (@TableTransactName + '_Open')


PRINT @FinallyBlockBegin

PRINT @FinallyBlockEnd


PRINT 'End Sub'

-------------------------------------------------------------------------
PRINT ''
PRINT 'Public Function ' + @TableTransactName + '_Browse(ByRef ReturnError As String, ByVal AccessKey As String) As ADODB.Recordset'

PRINT @TryBlockBegin


SET @S = NULL
SELECT @S = COALESCE(@S + ',' + Name, Name) FROM syscolumns WHERE id = object_id(@TableHeaderName) AND
iscomputed = 0
AND
(
CHARINDEX('_', Name) = 0
)
AND colid BETWEEN 1 AND 3
ORDER BY colid


SET @s = @Tab + 'Set ' + @TableTransactName + '_Browse = m_Database.NewRsOpen("SELECT ' + @s + ' FROM ' + @TableHeaderName + '")'


PRINT ''

print @s


PRINT ''

PRINT @TryBlockEnd

PRINT @CatchBlockBegin

PRINT dbo.CodeGenMt_CatchBlockEnd (@TableTransactName + '_Browse')

PRINT @FinallyBlockBegin

PRINT @FinallyBlockEnd


PRINT 'End Function'


-------------------------------------------------------------------------





-------------------------------------------------------------------------
PRINT ''
PRINT 'Public Function ' + @TableTransactName + '_Lookup(ByRef ReturnError As String, ByVal AccessKey As String) As ADODB.Recordset'

PRINT @TryBlockBegin


SET @S = NULL
SELECT @S = COALESCE(@S + ',' + Name, Name) FROM syscolumns WHERE id = object_id(@TableHeaderName) AND
iscomputed = 0
AND
(
CHARINDEX('_', Name) = 0
)
AND colid BETWEEN 1 AND 3
ORDER BY colid


SET @s = @Tab + 'Set ' + @TableTransactName + '_Lookup = m_Database.NewRsOpen("SELECT ' + @s + ' FROM ' + @TableHeaderName + '")'


PRINT ''

print @s


PRINT ''

PRINT @TryBlockEnd

PRINT @CatchBlockBegin

PRINT dbo.CodeGenMt_CatchBlockEnd (@TableTransactName + '_Lookup')

PRINT @FinallyBlockBegin

PRINT @FinallyBlockEnd


PRINT 'End Function'


-------------------------------------------------------------------------



PRINT ''

PRINT 'Public Sub ' + @TableTransactName + '_Delete(ByRef ReturnError As String, ByVal AccessKey As String, ' + @PkFields + ')'

PRINT @TryBlockBegin

PRINT @Tab + 'm_Database.BeginTrans'
print ''

SET @s = @Tab + 'Call m_Database.NewRsOpen("DELETE FROM ' + @TableDetailName + ' WHERE ' + @PkCondition + ')'

PRINT @s

SET @s = @Tab + 'Call m_Database.NewRsOpen("DELETE FROM ' + @TableHeaderName + ' WHERE ' + @PkCondition + ')'

PRINT @s

PRINT @Tab + 'm_Database.CommitTrans'

PRINT @TryBlockEnd

PRINT @CatchBlockBegin

PRINT @Tab + 'm_Database.RollbackTrans'

PRINT dbo.CodeGenMt_CatchBlockEnd (@TableTransactName + '_Delete')

PRINT @FinallyBlockBegin

PRINT @FinallyBlockEnd




PRINT 'End Sub'

PRINT ''

PRINT '''...' + @TableHeaderName + ' add/edit/delete'
















GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO