Change Crystal Reports db ip address in vb.net - sql-server

I am currently using VB.net for getting the reports in need with Crystal Reports, My access to the SQL database server is using windows authentication , and what i need to do is to be able to change the IP address of the database source , as i am accessing a test server now , and the code will go somewhere else for work.
What i've found:
this is the only way to change the database source
CrReport.SetDatabaseLogon("user", "password", "server", "RJCards")
but then again i am using windows authentication.
P.S: when i am changing the datasource on the report it self its working great, but since we moving the application to another place, it needs to be set manually like to be retrived from a variable or something.
here is a look over my code
Private Sub GetDuplicatedFF()
Dim CrReport As New DuplicatedFF
Dim CrExportOptions As ExportOptions
CrExportOptions = CrReport.ExportOptions
Try
CrReport.SetDatabaseLogon("user", "password", "server", "RJCards")
CrReport.ExportToDisk(ExportFormatType.Excel, My.Settings.defaultDir & "\DuplicatedFF_" & Format(Now.Date, "yyyyMMdd") & ".xls")
'My.Settings.defaultDir & "\DuplicatedFF_" & Format(Now.Date, "yyyyMMdd") & ".xls"
MsgBox("Done Exporting your file")
Catch err As Exception
MessageBox.Show(err.Message)
End Try
End Sub

When you use windows authentication or credentials to access a database through Crystal Reports, that means that the data retrieval SQL statements will be included inside the rpt file. This doesn't give you too much flexibility in scenarios where you need to make changes to IP addresses, database names, etc.
There is a different approach of providing data to the report with the use of a DataSet as a source. You simply add the necessary DataTables with the necessary columns to a DataSet, fill it with data and provide it to the report. So the rpt file won't include any
embedded information (such as SQL statements).
In order to convert an existing report file to use the aforementioned approach, you can use the following steps:
Create an xsd file in your application (Add New Item... → Data → DataSet)
Edit the DataSet and add the necessary DataTable(s) (Right click → Add → DataTable)
Edit the DataTable(s) and add the necessary column(s) (Right click on DataTable → Add → Column)
Edit each column and set its properties such as DataType etc (Left click on column → Change property inside property window)
Now you need to edit the report file and change the Datasource location (Double click on the report → left click on Database Fields in Field Explorer → Set Datasource Location...)
As a Datasource replacement choose ADO.NET (XML) and double click on Make New Connection. Choose the filepath of the xsd file (DataSet) and press finish.
Each DataTable must be paired with an existing Table inside "Current Data source:" by selecting the pair and pressing the Update button.
Now the report file will just have the necessary placeholders (columns) without any database connection or SQL statements. To load data to the report, use the code below (changed according to your needs).
Imports System.Data.SqlClient
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Windows Authentication Connection String'
Dim ConnString As String = "Server=MyServer;Database=MyDb;Trusted_Connection=Yes;"
'The SQL statement to retrieve data'
Dim SqlStatement As String =
<SQL>
SELECT
[column1]
,[column2]
,[column3]
FROM [MyDb].[dbo].[MyTable]
</SQL>
'A new instance to the DataSet that we created'
Dim MyDataSet As New DataSet2
'A new instance to the report file'
Dim MyReport As New CrystalReport1
'A new instance to the SQL adapter'
Dim SqlAdapter As New SqlDataAdapter(SqlStatement, ConnString)
'Fills the DataTable with data retrieved from the database'
SqlAdapter.Fill(MyDataSet.Tables("TestTable1"))
'Sets the DataSet as the report source'
MyReport.SetDataSource(MyDataSet)
'Previews the report'
CrystalReportViewer1.ReportSource = MyReport
End Sub
End Class

Related

system.data.sqlclientexception:incorrect syntax near '#p2'

I am trying to insert, update the data on Grid in VB.net windows application which has to update the data in database. I am not able to achieve this functionality using new schema name(Customer) but when I try to create table with schema "dbo" I am able insert, update the data on grid and able to see the data in SQL Server as well.
Please help me what I need to change in code perform insert and update options.
code:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim test1 As String
test1 = "Select * from Customer.CustomerID"
connection = New OleDbConnection
connection.ConnectionString = "Provider=MSOLEDBSQL.1;Integrated Security=SSPI;Initial Catalog=prod;Data Source=IN-TESTVM;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=IN-TESTVM;Use Encryption for Data=False;Tag with column collation when possible=False;MARS Connection=False;DataTypeCompatibility=0;Trust Server Certificate=False;Application Intent=READWRITE;MultisubnetFailover=False;Use FMTONLY=False;"
connection.Open()
myDA = New OleDbDataAdapter(test1, connection)
dsDataGrid = New DataSet
myDA.Fill(dsDataGrid)
grid.DataSource = dsDataGrid.Tables(0)
bindsrc2.DataSource = dsDataGrid
connection.Close()
End Sub
Button click event code is like as below
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
app = New OleDbCommandBuilder(myDA)
bindsrc2.EndEdit()
myDA.Update(bindsrc2.DataSource) 'Hitting the error while updating the data at this line
End Sub
I am able to load the data into grid using the schema name other than dbo as well.
myDA.Fill(dsDataGrid)
grid.DataSource = dsDataGrid.Tables(0)
bindsrc2.DataSource = dsDataGrid
Error message after clicking save button
Try setting the QuotePrefix and QuoteSuffix of your command builder to "[" and "]" respectively. As you are using a wildcard in your query, the command builder will not escape column names automatically and that means that keywords or spaces or other special characters will cause syntax errors.
Note that there are two alternatives. One is to not use a command builder at all and create your own action commands. In that case, you write the SQL so you escape the column names that need it. The other is to not use a wildcard in the query, in which case you will escape the column names that need it and the command builder will follow suit.

Using VBA in MS Word, open a Word document data from inside image column in SQL Server

First I created a table in a SQL Server database with columns like document id, docname and docdata.
Second I managed to upload a document into that table using MS Access and ole object and now I have a word document there, by double click the ole object in the MS Access form interface I could open the document.
What is interesting about this is that I can edit the document and get the changes saved to the document inside the server.
The idea is that I want to use the SQL Server over our LAN-network as an alternative to OneDrive and make collaborative working possible to my coworkers with no internet service.
Now I am trying to open that document using using VBA in MS Word.
Here is my vague attempt:
Option Explicit
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Private Sub CommandButton1_Click()
' my own connection string
cn.Open "provider=sqloledb;server=127.0.0.1,1433;database=accessdb;UID=sa;PWD=111111"
With rs
Set .ActiveConnection = cn
.Source = "select * from docs where did=1"
.LockType = adLockOptimistic
.CursorType = adOpenKeyset
.CursorLocation = adUseClient
.Open
End With
Dim WordObj As Word.Application
'rs![docdata].Verb = -2
'rs![docdata].Action = 7 ' Activates the application.
Dim obdoc As Word.Document
Set obdoc = rs![docdata] ' what property to attach here ??
obdoc.SaveAs2 "D:\thisdoc.doc"
WordObj.Documents.Open obdoc
WordObj.Activate
End Sub
A mismatch error pops up and I did not know how to deal with this, what type of property should retrieve the data from that field and assign it to the newly made document.
Update 20-2-2020
Um, Now I recognized that the Ms-word document isn't a simple RTF file.
It is a zipped folder ! see this !
and in order to verify this I removed the .docx extension and replaced it with .zip,
then I unzipped it and got some folders inside of them a few .xml files..
This means that the upper approach is not compatible with the nature of this file. type.

Saving OLE Objects in Access field with VBA

I know that this subject has been covered to large extend, but I have not been able to find a solution to my particular problem.
I have a table with a column Attachments of OLE Object data type. The back end of the table is SQL Server table with VARBINARY(MAX) data type for Attachments column.
If I right-click on the Attachments field in Access, a menu pops-up with an option to Insert Object... Following this path I could insert a file in the field.
The file inserted this way could be opened for viewing and editing just by double-clicking the field.
Now. I need to do the same using VBA. I need to take the list of files and insert them in the Attachments field in the appropriate rows. This should not be a difficult task as it is widely known how to insert a file in a field using ADODB.Stream. The following is a simple code to try the concept:
Private Sub POC()
Dim db As DAO.Database
Dim rsa As DAO.Recordset
Dim stream As ADODB.stream
Set db = CurrentDb()
Set rsa = db.OpenRecordset("ZipCodeAttachments", dbOpenDynaset, dbSeeChanges)
rsa.MoveFirst
rsa.MoveNext
rsa.Edit
Set stream = New ADODB.stream
stream.Type = adTypeBinary
stream.Open
stream.LoadFromFile Application.CurrentProject.Path & "\Attachments\537.zip"
rsa.Fields("Attachments").value = stream.Read
rsa.Update
rsa.Close
Set rsa = Nothing
Set dba = Nothing
End Sub
The code inserts a file in the Attachments field of the second row. I could validated that value has been added via SSMS. However, when I try to open the field for viewing and editing as I did earlier with the first row, this time I am getting an error:
Clearly, there is something wrong with the way the file is saved with VBA.
What am I doing wrong? How to achieve the same result with VBA as I get with Access user interface?
If you want to store a file as an OLE Package shell object, doing some GUI coding (opening a form with an OLE object, then using that to store the file) is the only way as far as I know.
Create an unbound form called frmLoadOLEObj, with on it a bound OLE object called MyBoundOLEFrame.
On the form, add the following code:
Public Sub SaveOLEObj(rs As DAO.Recordset, fldName As String, FileName As Variant)
'Save the position of the recordset
Dim bkmrk As Variant
bkmrk = rs.Bookmark
'Bind the form to the recordset
Set Me.Recordset = rs
'Move the form to the saved position
Me.Bookmark = bkmrk
'Bind the OLE frame to the field
MyBoundOLEFrame.ControlSource = fldName
MyBoundOLEFrame.Class = "Package"
'Load the attachment into the OLE frame
MyBoundOLEFrame.SourceDoc = FileName
MyBoundOLEFrame.Action = acOLECreateEmbed
End Sub
Then, to add a file to a record:
Dim rsa As DAO.Recordset
Set rsa = CurrentDb.OpenRecordset("ZipCodeAttachments", dbOpenDynaset, dbSeeChanges)
Dim frmOLE As New Form_frmLoadOLEObj
frmOLE.SaveOLEObj rs, "Attachments", Application.CurrentProject.Path & "\Attachments\537.zip"
As you can see, this is very "hacky" code, because it runs GUI operations, and you have code on a form that is not a form, but really a module, but you need a form to put the control on because you can't have the control without the form. I'd rather have a BLOB any day.

Creating an imports program to clear a database and migrate new data

Over the last few days, I was asked to move a company program over from an Access back-end, to SQL Server.
There are 2 copies of the program, the live data version, on the server, and the local version on my PCs C: Drive, to ensure if I make a mistake, it doesn't affect the live data.
So, I managed to migrate the Access database, tables and data over to SQL Server 2008, and the local version of the program now works.
The easiest way, or so I'm informed, to now do the same to the live version of the program, is to write an imports program, which wipes all of the data from each table in the SQL Server database, and then copies over the data from the live Access database. However, I've never done this before, so I'm not really even sure where to begin.
Could anybody point me in the right direction on how to begin or do this, so that I only have to change the connection path in the program, rather than go through the whole process again?
PS, I work in vb.net, so that's the language I would need any responses in!
Thanks.
Usually one uses the SQL Server Import and Export Wizard for this.
It's a separate tool that is installed with SQL Server Management Studio (SSMS).
ANSWER
Step 1;
I added a new path to the ini file for the database to read. This connected to the live database. Once this connection is open in the project, proceed to step 2.
Step 2;
Create a new class, where the imports and exports will happen.
Step 3;
Put a button, or some sort of control in the program to initiate the import/export. For example, I had a button which, when clicked, asked the user to confirm that they wanted to import a new database and overwrite the existing one. If yes, call the function which does this, in the newly made imports class.
Step 4;
Now that you know how to get this set up, the code would be something like
Public Function importdatabase(/connections go in here/)
Declare transaction
Create sql variable
Try
Begin the transaction here
sql to delete the data from one table
sql to select all data from database that is being imported
For loop to iterate over each record in the database table
Declare a variable for each field in the database
variable1 = ("fieldname1")
variable2 = ("fieldname2")
sql statement to insert the new values
call to the function which runs the sql query
Next
commit transaction
Catch ex As Exception
Throw
End Try
Step 5; Repeat the delete/insert process for each database table
Below this, I have other functions.
One function created a new datatable, this is referenced as
For each dr as datarow in /functionname(parameters).Rows
Next one is to execute the sql statement (not required, any command to execute it will do)
Next one is used for parameterising my SQL query
The rest are to replace null values in the database with empty strings, set dates, etc
You can use the following class to import table(s) in access to sql server.
You need:
- The connection string of the source (including access file name) and the target one.
- The Source Table ,target tatble (if null it is the same as the source table)
Class ImportHelper
'modify connectionstring as needed
Public Property SourceConnectionString() As String
Get
Return m_SourceConnectionString
End Get
Set
m_SourceConnectionString = Value
End Set
End Property
Private m_SourceConnectionString As String
Public Property DestinationConnectionString() As String
Get
Return m_DestinationConnectionString
End Get
Set
m_DestinationConnectionString = Value
End Set
End Property
Private m_DestinationConnectionString As String
Public Sub New(sourceConnectionString__1 As String, destinationConnectionString__2 As String)
SourceConnectionString = sourceConnectionString__1
DestinationConnectionString = destinationConnectionString__2
End Sub
Public Sub Import(sourceTable As String, Optional targetTable As String = Nothing)
Using sourceConnection = New OleDbConnection(SourceConnectionString)
If String.IsNullOrEmpty(targetTable) Then
targetTable = sourceTable
End If
sourceConnection.Open()
' Perform an initial count on the destination table.
Dim commandRowCount = New OleDbCommand(Convert.ToString("SELECT COUNT(*) FROM ") & sourceTable, sourceConnection)
Dim countStart As Long = Convert.ToInt32(commandRowCount.ExecuteScalar())
Console.WriteLine("Source Table [{0}] has {1} rows", sourceTable, countStart)
' Get data from the source table
Dim commandSourceData = New OleDbCommand(Convert.ToString("SELECT * FROM ") & sourceTable, sourceConnection)
Dim reader = commandSourceData.ExecuteReader()
'---------------
Using destinationConnection As New SqlConnection(DestinationConnectionString)
destinationConnection.Open()
Using bulkCopy As New SqlBulkCopy(destinationConnection)
bulkCopy.DestinationTableName = targetTable
Try
' Write from the source to the destination.
bulkCopy.WriteToServer(reader)
Console.WriteLine(Convert.ToString("Sucess Importing ") & sourceTable)
Catch ex As Exception
Console.WriteLine(ex.Message)
Finally
reader.Close()
End Try
'using
End Using
'using
End Using
End Using
'using
End Sub
End Class
How to use:
Private Sub Test()
'modify connectionstring as needed
'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\mydatabase.mdb;User Id=admin;Password=; //access 97..2000
Dim SourceConnectionString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\temp\database1.accdb;Persist Security Info=False;"
Dim DestinationConnectionString As String = "Data Source=xxxx;Initial Catalog=test;user=xxx;password=xxx;"
New ImportHelper(SourceConnectionString, DestinationConnectionString).Import("table1", "test1")
End Sub

Creating a SQL Server database for the first time at run time

I want to create a SQL Server database at runtime in my vb.net project. I know how to actually code the database but I am wondering where should I actually put the code? Should I be putting the code in the start up form or should it go into a class on it's own? Also, this project will be going on more than one pc at a particular site, so I only want the database to be created the first time the project is activated and then just be able query the database on different pcs after that. How do I do this? All help on this matter would be greatly appreciated.
EDIT:
Ok, so I should have been clearer on this. The project is going to be on 2 different pcs, it is for visitors entering a business. The pcs will be in reception and security. I need both pcs to access the same database with the same details in it. I don't want to have two different databases where details have to be put in twice. For example, if I enter at reception today and then go through security tomorrow, then all I should have to enter in security is why I'm entering the business again, I shouldn't have to put my details in a second time. How do I go about this? As I already said, I know how to code the database, but I want to know how to do what I stated in my question.
Thanks in advance for all help given.
If you add the code in module or in form load then it will execute all the time when the form loads. it is wasting of time to check whether the database exist or not in each run. So it is better to place a button with text "Create database" for this purpose(or menu item). it's click event will load the database. the following code can be used to create the database dynamically on button click
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'creating and initializing the connection string
Dim myConnectionString As SqlConnection = New SqlConnection("Data Source=(local)\SQLEXPRESS;Initial Catalog=master;Integrated Security=True;Pooling=False")
'since we need to create a new database set the Initial Catalog as Master
'Which means we are creating database under master DB
Dim myCommand As String //to store the sql command to be executed
myCommand = "CREATE database my_db" //the command that creates new database
Dim cmd As SqlCommand = New SqlCommand(myCommand, myConnectionString) // creating command for execution
Try
cmd.Connection.Open() //open a connection with cmd
cmd.ExecuteNonQuery() //Execute the query
cmd.Connection.Close() //Close the connection
Catch
MsgBox(" Already installed database", MsgBoxStyle.Critical, " MaS InfoTech- Warning")
End Try
'Creating table to the dynamicaly created database
Try
Dim cn As SqlConnection = New SqlConnection("Data Source=(local)\SQLEXPRESS;Initial Catalog=my_db;Integrated Security=True;Pooling=False")
'here the connection string is initialized with Initial Catalog as my_db
Dim sql As String //sql query string
sql = "CREATE TABLE customer(cus_name varchar(50) NULL,address varchar(50) NULL,mobno numeric(18, 0) NULL,tin varchar(50) NULL,kg varchar(50) NULL)"
cmd = New SqlCommand(sql, cn) // create command with connection and query string
cmd.Connection.Open()
cmd.ExecuteNonQuery()
cmd.Connection.Close()
Catch
MsgBox(" Already existing table", MsgBoxStyle.Critical, " MaS InfoTech- Warning")
End Try
End Sub

Resources