URGENT!!! How to switch DB with VB6 and CR8.5?

We have 2 environments : Development and Live, and reports are being moved from one to another.
Problem is that the reports point to different db's on different servers.

I want to make the db switch from a VB6 application (or VB.NET) so that there is no manual action needed.

The DB is a SQL Server 2000 and the connection in the reports is defined as OLEDB for SQL Server.

Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

This samples shows how using an Access database.  The steps are the same for MS SQL


sky71276Author Commented:
I already saw that sample, but it didn't do the trick...

*** I will be out of the office until monday, so it isn't that urgent anymore, the points remain though ***
This is the code I use in the same environment you are working in.  This is for a SQL server database using the native SQL drivers in Crystal.  The key for your needs are the variables dbLocSQL and dbDatabaseName.

  dim dbUserID as string
  dim dbUserPass as string
  dim dbLocSQL as string
  dim dbDatabaseName as string
  dim RptFileName as string
  dim crApp as CRAXDRT.Application
  Dim crRepp As CRAXDRT.Report
  Dim crDBTab As CRAXDRT.DatabaseTable
  ' Get user login ID and password
  dbUserID = "someuser"
  dbUserPass = "mypassword"

  ' Define the SQL server to use.  This is the name of the server itself
  dbLocSQL = "SQLSvrName"

  ' Define the database within the SQL server to use
  dbDatabaseName = "MyDatabase"

  ' What Report to Print?
  RptFileName = "MyReport.RPT"

  ' Open The Report File
  Set crRepp = crApp.OpenReport(App.Path & RPTFileName)

  ' Set location of database based on stated SQL Server Name
  crRepp.Database.LogOnServer "p2ssql.dll", dbLocSQL, dbDatabaseName, dbUserID, dbUserPass

  ' Set table location to appropriate company server
  For Each crDBTab In crRepp.Database.Tables
    crDBTab.SetLogOnInfo dbLocSQL, dbDatabaseName, dbUserID, dbUserPass
  ' Turn on the broken Crystal Reports progress box.  Doesn't work.  Maybe someday.
  crRepp.DisplayProgressDialog = True

  ' Force Portrait orientation
  crRepp.PaperOrientation = crPortrait

  ' Associate report with the viewer
  CRViewer1.ReportSource = crRepp

  ' Display the report

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
CompTIA Security+

Learn the essential functions of CompTIA Security+, which establishes the core knowledge required of any cybersecurity role and leads professionals into intermediate-level cybersecurity jobs.


I don't tknow that my suggestion will help you with your current problem, but it may be usefull if you decide to make some design changes.

General Concept (This is the same concept I argued {and won} here at my place of employment):
   The functional users (at large) cannot be expected to have knowledge of how relational databases work.   It may also be prudent to hide a lot of data from functional users as most data in databases are not pertinant to functional data.  Therefore, I propose that a series of public views be created that the functional users are allowed to use for creating reports.  These views are the only entities that reports can be written from (no tables).
    All reports should be run using an ODBC connection.  ODBC connections can be created dynamically in code and used only for the life of the database connection to retrieve data.  This does two things: 1) locks down data/reports only to specified users with proper access.  2) Limits access to report access *ONLY* through your application _unless_ someone from IT has been given the proper authority to install the ODBC connection.  Which again means no unauthorized access.

The huge benifit to using ODBC when it comes to reports is that the report references the ODBC as if it were the Database name, and as you know ODBC is a dynamic connection to some database somewhere.

Now... the ODBC thing can be done directly against database tables (not necessarrily views).  The reason I explicitly state views is because of not only the above mentioned reason (lack of database knowledge), but also because either the program or the database can specify which views a user has access to.  Utiliziing role level security is a huge benifit to a corporation.


Use ODBC connections for reports. It may be a little slower than adirect OLEDB connection, but... hey this is a report.  It shouldn't have intense database processing with tons of cummunication back and forth.  You should make one request and receive a data payload.  That's it.

my personal preference is on ole db, it tends to be heaps faster, and i leave the db security to sql server. if you want to restrict access to tables or rows, then create different users with different rights and provide everyone with the appropriate user name / password.

if you are using the rdc in cr 9, then use connectionproperties and the table location to change database

Dim crxDatabaseTable As CRAXDRT.DatabaseTable
For Each crxDatabaseTable In Report.Database.Tables
  With crxDatabaseTable.ConnectionProperties
    .Item("Provider") = "Provider Name"
    .Item("Data source") = "Server Name"
    .Item("Initial Catalog") = "Database Name"
    .Item("User ID") = "UID"
    .Item("Password") = "PWD"
  End With
  crxDatabaseTable.Location "database.dbo." + crxDatabaseTable.Name
Next crxDatabaseTable

also check this
sorry, i hadn't seen you are in 8.5. here this should do the trick
Dim myReport As CRAXDRT.Report
Dim myTable As CRAXDRT.DatabaseTable
For Each myTable In myReport.Database.Tables
  myTable.SetLogOnInfo "ServerName", "DatabaseName", "User", "Password"
  myTable.Location = "Database.dbo." + myTable.Name
EwaldL - I think I already posted similar code above.
your code was missing the tableobject's location method. according to my experience this method is essential when pointing to a different SQL Server database at runtime. it needs to be executed in case the fully qualified table name changes.
I'll buy that.  I don't ever use it.  I guess my databases are more stable than yours.  No offense meant.
nothing to do with stability, just with the fact that the fully qualified table name in sql server contains the database name.

no offence taken, no offence meant...

Instead of Developing DBSwitch you can set the path at runtime in crystal report because it would be better to write a generalize code.

You can write the following code
First decleare a recordset of the table which you r using in crystal report.

then write the following code

Report.Database.setdatasource rs,3,1
If you are using multiple tables then use
Report.Database.setdatasource rs2,3,2  ' and so on

sky71276Author Commented:
Although I never got to what I exactly wanted, the accepted answer provided me with very useful code. When I read _TAD_ 's answer, I realized that a design change is more what we really want instead of a quick patch.

Thanks for the effort.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Crystal Reports

From novice to tech pro — start learning today.