Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

SQL queries ok with adodc control in vb6 but no go in Crystal 2

Status
Not open for further replies.

TNN

Programmer
Sep 13, 2000
417
US
I am using crystal reports 9.0 via the RDC in vb6.0.
A SQL statement that will work in vb6.0 with a ADODC data control will not be accepted as a SQL expression field in the RDC for Crystal. The database properties and oleDB provider are the same for both yet the SQL statement works in VB but not in the SQL expression field in the RDC. Can anyone guess why???

TNN, Tom


TOM
 
Are you trying to use a SQL Expression field to return a resultset? That's not the purpose of SQL Expression fields. At best, they can return the result of a statement like (Select Max(fieldname) from table). But their primary purpose in life is to perform a SQL function on the server. For example, you may want to return the first 254 characters from a text or memo field, and you can use a SQL Expression to perform this function on the server before the resulset defined by Crystal's visual linking expert and record selection formula is returned to the report.
 
FVTrainer,

Yes, I was trying to return a result or recordset. I guess I should have been using a command object.

I'm new at this. Thank You.

TNN, Tom



TOM
 
What are you trying to accomplish? Are you trying to create the recordset for the report?
 
FVTrainer,
Yes, I am trying to create the recordset for the report. From the database I am wanting to create a record for each selected employee and then use the fields in the recordset for my report.
TNN, Tom


TOM
 
It would seem to me that if you are comfortable creating the recordset in vb, then you should really create your report to use an ADO recordset (i.e., use the Active Data driver) rather than trying to adjust the command object at runtime. There are a few different paths to take to get there, but before we go through the techniques, please answer the following questions:

1) Are you using a Crystal report that is external to the vb application (i.e., it is an .rpt file) or are you using a crystal report that is defined in a dsr file in vb?

2) You mentioned using an adodc recordset. Is that your preferred method for collecting the data the report? If not, how exactly would you want to build the recordset?

3) Is the desired recordset for the report based on sql statement/stored procedure that always returns the same field list? In other words, are the field names, data types, and sequence always the same in the recordset for the report?
 
FVTrainer,
Sorry I'm so late in responding. In answer to:

1)I am using a crystal report that is defined in a dsr file in vb.

2)I have been building the recordsets with SQL statements in the command object. This is preferred. I was only using the adodc, in VB, to test the SQL statement.

3)Yes, the field names, data types, and sequence are always the same. They would only change if I were to modify the database for design purposes, but then the SQL would probably change.

I'm not sure what you mean by adjust the command object at run time??

TNN, Tom


TOM
 
Well, the command object available in Crystal is fine. If your sql statement won't need to change in terms of the joins and the where clause (or any filters in the where clause that need to be determined at runtime can be handled via parameters in the command object) then don't worry about using an ADO recordset. In terms of performance, I don't think you'll see a difference, assuming you are writing efficient sql statements. However, one of the advantages of using an ADO recordset is that the Crystal report does not have any connectivity to the database (you don't have to pass logon info). So you remove one layer of potential problems.
 
FVTrainer,

You lost me.

Are you saying create an ADO recordset via vb6 and then somehow use it in the crystal report??? If so, how??

Is not Crystal creating an ADO recordset when using the command object?? In Crystal, in the DataBase Expert, the properties for the connection show OLEDB(ADO).

I would like to understand what you are saying. Thank You.

TNN, Tom




TOM
 
Well, in the case of a command object, Crystal is using an OLEDB connection (whether or not that means it is an ADO recordset is, perhaps, a matter of interpretation). But with a command object, you define, within Crystal itself, a query. So, Crystal has to have connectivity to the database. And, as far as I know (and I could be wrong here), the sql statement in the command object itself is not modifiable at runtime. You can, of course, use parameters to make the sql statement flexible, but items like the From clause are set in stone (I think) and the WHERE clause, while somewhat flexible, won't be highly dynamic.

Not so, however, when using an ADO recordset, created in vb, to populate a Crystal report. The basic idea here is that you create a report in Crystal using the Active Data driver and either supplying a ttx file (data definition file) or a sql statement as the basis for building the report (i.e, the sql statement provides a recordset at design time that will you allow you to create the report). But at runtime, the report itself has no connectivity to the database and simply is a recipient of a recordset handed to it by vb. So vb does the query, gets an ADO recordset, and pushes it into the Crystal report.

The primary advantages are that the sql can be entirely dynamic. Based on user input, the vb app can get the recordset from Server A or Server B (or C etc., or Database X or Database Y). The Where clause can be as dynamic as necessary, based on vb logic. And all connectivity (logging onto the database, etc.) is handled solely by your ADO connection in vb. The only limitation is that the schema of the recordset passed at runtime has to match the schema used to create the report. That means that the the field list has to be identical in terms of name, order, and data types.

Below is sample code that illustrates the use of an ADO-based Crystal report:

Form frmMain
----------------------
Option Explicit
Dim cn As New ADODB.Connection
Dim rs As ADODB.Recordset
Dim strUser As String
Dim strPswd As String
Dim strDatabase As String
Dim strServer As String

Dim crApp As New CRAXDRT.Application
Public crRpt As CRAXDRT.Report
Const cSalesOrders As String = "SalesOrders.rpt"

Private Sub Form_Load()

'This application uses an ADO 2.5 connection to the Northwind database
'in SQL Server. Use appropriate UserNames and Passwords for your connection

'Declare variables

Dim strConnection As String
Dim strSQL As String

'the server, database, and logon info are hardcoded for this illustration

strUser = "green"
strPswd = "password"
strDatabase = "Northwind"
strServer = "dell-laptop"

'Build the connection string
strConnection = "Provider=SQLOLEDB.1;Persist Security Info=False;"
strConnection = strConnection & "User ID=" & strUser & ";"
strConnection = strConnection & "Password=" & strPswd & ";"
strConnection = strConnection & "Initial Catalog=" & strDatabase & ";"
strConnection = strConnection & "Data Source=" & strServer

'Open the connection
cn.ConnectionString = strConnection
cn.Open

'Build the sql statement that will allow us to populate the
'drop down for the user interface

strSQL = "Select Distinct Country from Customers"

Set rs = New ADODB.Recordset
rs.Open strSQL, cn, adOpenKeyset, adLockReadOnly

'Populate the combobox
cboCountry.Text = "USA" 'default value
If Not rs.BOF Then
rs.MoveFirst
Do Until rs.EOF
cboCountry.AddItem rs.Fields(0).Value
rs.MoveNext
Loop
End If

'Cleanup

rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing
End Sub

Private Sub cmdPreview_Click()

'Now we need to get an ado recordset that corresponds to the
'schema used to create the report and then pass the ado recordset
'to the report.

Dim rs As ADODB.Recordset
Dim strConn As String
Dim strSQL As String
Dim strCountry As String

'Crystal objects
Dim crDB As CRAXDRT.Database
Dim crTable As CRAXDRT.DatabaseTable

strCountry = cboCountry.Text

'Now Build a valid SQL Statement with strCountry as a dynamic value
strSQL = "SELECT "
strSQL = strSQL & "c.CustomerID, c.CompanyName, c.Region, c.Country, c.Phone, "
strSQL = strSQL & "c.ContactName, c.ContactTitle, "
strSQL = strSQL & "o.OrderID, o.OrderDate, o.ShippedDate, o.RequiredDate, "
strSQL = strSQL & "d.ProductID, d.UnitPrice, d.Quantity, d.Discount, "
strSQL = strSQL & "p.ProductName , p.ProductID "
strSQL = strSQL & "From "
strSQL = strSQL & "Customers c INNER JOIN Orders o "
strSQL = strSQL & "ON c.CustomerID = o.CustomerID "
strSQL = strSQL & "INNER JOIN [Order Details] d "
strSQL = strSQL & "ON o.OrderID = d.OrderID "
strSQL = strSQL & "INNER JOIN Products p "
strSQL = strSQL & "ON d.ProductID = p.ProductID "
strSQL = strSQL & "Where "
strSQL = strSQL & "c.Country = '" & strCountry & "'"

'Now establish the ado connection, using the module level
'variables for logon info
strConn = "Provider=SQLOLEDB.1;Persist Security Info=False;"
strConn = strConn & "User ID=" & strUser & ";"
strConn = strConn & "Password=" & strPswd & ";"
strConn = strConn & "Initial Catalog=" & strDatabase & ";"
strConn = strConn & "Data Source=" & strServer

'Open the ado connection
cn.ConnectionString = strConn
cn.Open
'Create the ado recordset
Set rs = New ADODB.Recordset
rs.Open strSQL, cn, adOpenKeyset, adLockReadOnly

'If we have records in the recordset
If Not rs.BOF Then
'Now Open report
Set crRpt = crApp.OpenReport(App.Path & "/" & cSalesOrders)

'Get rid of any data saved in the report
crRpt.DiscardSavedData

'Get the Database object
Set crDB = crRpt.Database

'an ado report should only have on table, so we can get it
'directly using the Item property of the Tables collection
Set crTable = crDB.Tables.Item(1)

'Pass the ado recordset to the database table
crTable.SetDataSource rs, 3

'Now read the records into the report before the rs goes out of scope
crRpt.ReadRecords

'and view the report
frmViewer.Show vbModal

Else
MsgBox "No Data For Report"
Exit Sub
End If

rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing

End Sub
--------------------------------


Form frmViewer
--------------

Private Sub Form_Load()

'Assign the report from the previous form to the viewer
CRViewer91.ReportSource = frmMain.crRpt
'Set the magnification factor
CRViewer91.Zoom 100
'Maximize the form
Me.WindowState = 2
'View the report
CRViewer91.ViewReport


End Sub

Private Sub Form_Resize()

CRViewer91.Left = 0
CRViewer91.Top = 0
CRViewer91.Width = ScaleWidth
CRViewer91.Height = ScaleHeight

End Sub
 
FVTrainer,
Thank You for the instructions and code. This will take a while to digest but I think I understand the concept and the advantages. Thanks again.
TNN, Tom


TOM
 
Thanks FVTrainer! I was looking around for something like this to use with Crystal and VB. You got me started!

Have a great day!

j2consulting@yahoo.com
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top