Using ASP / VBScript to write to an Excel File - forms

I am trying to take information from a HTML Form and input into an Excel File (xlsx) with ASP / VBScript (not VB.NET). I have some experience in Java and PHP but am new to the VB world.
Sofar I have found ways to get the Data from the GET/POST methods. Now I am trying to create an ADO connection to the excel file.
here is my code so far:
Dim cn as ADODB.Connection
Set cn = New ADODB.Connection
With cn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = "Data Source=EXCEL_FILE.xlsx;" & _"Extended Properties=Excel 12.0 Xml;HDR=YES"
.Open
End With
I got the connection String from here: connectionstrings.com
and tried to stick to this guide: http://support.microsoft.com/kb/257819/en-us
But no luck up until now.
So here are my questions:
1) Is this the right idea in general? So grabbing the Data from POST for example and then opening a connection with ADO to the excel file and adding the info with queries on the connection object?
2) Any obvious flaws in the code ?
3) Would be great if someone could outline a solution, writing data from a HTML Form into an Excel file.
Thanks in advance.
Edit:
Ok Here is the code I try:
Dim cn
Set cn = Server.CreateObject("ADODB.Connection")
With cn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = "Data Source=EXCEL_FILE.xlsx;Extended Properties=""Excel 12.0 Xml;HDR=YES"""
'From : http://www.connectionstrings.com/excel-2007
.Open
End With
Once I call "Open" on cn it gives me a 500 internal Error. I am not sure if I am making an obvious mistake, but since I don't know where to find error logs I don't have a clue where to start looking.

1 - If you have to use Excel as database, yes it's right. But, if you need a database, should use a database, not an excel sheet.
2 - VBScript doesn't support early binding. You should define variables without data type, should create objects using CreateObject. And you need to some changes in connection string (quotes).
e.g.
Dim cn
Set cn = Server.CreateObject("ADODB.Connection")
With cn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = "Data Source=EXCEL_FILE.xlsx;Extended Properties=""Excel 12.0 Xml;HDR=YES"""
'From : http://www.connectionstrings.com/excel-2007
.Open
End With
'
' Add new records etc.
'
cn.Close
Set cn = Nothing
3 - An example to add new record (put the instead of above 'Add new records etc.) gets the values from HTML Form (post method).
Dim rs
Set rs = Server.CreateObject("Adodb.Recordset")
With rs
.Open "[Sheet1$]", cn, 1, 3
.AddNew
.Fields(0).Value = Request.Form("Param1") 'Column A1 (or with name rs.Fields("col1").Value = exp )
.Fields(1).Value = Request.Form("Param2") 'Column B1
.Update
.Close
End With
Set rs = Nothing

Related

How to connect to DB2 from Lotus Notes Client via LotusScript?

Just simple using JDBC driver in Java agent works fine. Now I need to connect DB2 from LotusScript. There are many articles like those:
http://www.proudprogrammer.no/web/ppblog.nsf/d6plinks/GANI-9DFMRB
https://openntf.org/XSnippets.nsf/snippet.xsp?id=db2-run-from-lotusscript-into-notes-form
but they use ODBC connection or something else. Anyway I don't see where I can define DB2 host and port in my LotusScript agent. Users won't be able to configure ODBC connection on each workstation. I need some Domino native method to connect to DB2. Or where do I define DB2 host/IP and port in this example:
https://openntf.org/XSnippets.nsf/snippet.xsp?id=db2-run-from-lotusscript-into-notes-form
You could use LSXODBC library but that is deprecated so you probably shouldn't.
The current supported method is to use the LSXLC library but be warned that it provides a very OO-centric approach to sending/consuming data but it is very quick and if you use it as designed, can make moving data from one data provider (say Notes) to another (say DB2) somewhat easy.
If you want to stick with standard SQL strings you can still do that with LSXLC with the "execute" method off of the LSConnection object.
As far as connecting to it goes you just need to make sure the appropriate driver is installed on the machine and then use the appropriate connection parameter in the when creating a new LSConnect object (e.g., ODBC2 for ODBC, DB2 for the CLI DB2 driver, OLEDB for an SQL OLE driver, etc).
If you stick with ODBC or OLEDB you can control the connection string via code. If you use the CLI DB2 driver (which is very, very fast) you need to configure the connection on each machine the driver is installed on.
All this is documented in the Designer help but it is, in my opinion, not organized in the best fashion. But it is all there.
So, some example code that has been largely copied from some code I have sitting around and is not tested is:
Option Declare
UseLSX "*lsxlc"
Sub Initialize
Dim LCSession As LCSession
Dim lcRDBMS As LCConnection
dim lcFieldList as new LCFieldList()
dim lcField_FirstName as LCField
dim lcField_LastName as LCField
dim strFirstName as string
dim strLastName as string
dim strConnectionType as string
' Hard-coding this here just for this example
' I think you will either want an ODBC (odbc2) or a CLI DB2 (db2) connection
strConnectionType = "odbc2"
Set lcRDBMS = New LCConnection (strConnectionType)
' Set some standard properties on the LCConnection object
lcRDBMS.Userid="<userid>"
lcRDBMS.Password="<password>"
lcRDBMS.MapByName=True
' Properties and property values that are different
' depending on the connection type
select case strConnectionType
case "odbc2" :
' Use the DSN name as configured in the ODBC Control Panel (if on Windows)
lcRDMBS.Database = "<SYSTEMDSN>"
case "oledb" :
lcRDBMS.Server = "<myserver.company.net>"
lcRDBMS.Provider = "sqloledb"
lcRDBMS.Database = "<my_database_name>"
' Not sure this actually changes anything or is even setting the correct property
' But the intent is to make sure the connection to the server is encrypted
lcRDBMS.INIT_ProviderString = "ENCRYPT=TRUE"
case "db2" :
' I am afraid I have lost the connection properties we used to use
' to form up a DB2 CLI connection so the following is just a best guess
' But if you are not going to be using the advance features of LSX to
' connect to DB2 you might as well just a standard ODBC driver/connection
lcRDBMS.Database = "<connection_name>"
End Select
Call lcRDBMS.Connect()
' This call returns a status code and populate the lcFieldList object with our results
lngQueryStatus = LcRDBMS.Execute("<Select FirstName, LastName from SCHEMA.Table WHERE blah>", lcFieldList)
If lngQueryStatus <> 0 Then
If lcFieldList_Destination.Recordcount > 0 Then
' Get our fields out of the lcFieldList object before going into the loop.
' Much more performant
Set lcField_FirstName = lcFieldList.Lookup("FirstName")
Set lcField_LastName = lcFieldList.Lookup("LastName")
While (lcConn.Fetch(lcFieldList) > 0 )
strFirstName = lcField_FirstName.Text(0)
strLastName = lcField_LastName.Text(0)
' Do something here with values
Wend
End If
End If
End Sub

Create Access reports from Form and save as PDF

Im currently using an Access database to create alot of reports - the report is made using a Query as a source, in the Query i use a Form as criteria so that the open page in the Form is the data used in the report.
Then I save the report as a PDF and click in the form to run the next set of data.
That is very time consuming when i have over 500 reports to make. So is there a way to make a function, a VBA or macro to run through all pages in the form and save each report as a PDF?
My form is named NorwF, the query is NorwQ and the report is NorwRap
I hope that makes sense and that there is a faster way to make this projekt run smoothly.
If you place a button on the form, this code behind should work:
Dim rst As DAO.Recordset
Dim strReport As String
Dim strReportFile As String
strReport = "NorwRap"
'Set rst = Me.RecordsetClone
Set rst = CurrentDB.OpenRecordSet("NorwQ") 'use the query
Do While rst.EOF = False
strReportFile = rst!ID & ".pdf" ' give report name based on field name
DoCmd.OpenReport strReport,acViewPreview , , "id = " & rst!ID
DoCmd.OutputTo acOutputReport, strReport, acFormatPDF, strOutFile
DoCmd.Close acReport, strReport
rst.MoveNext
Loop

How to refresh/requery report in access VBA before auto-exporting it on database launch

I searched thoroughly and tried many different solutions, but I can't seem to get it to work, even though it shouldn't be that difficult.
I have an access database which automatically sends reports by e-mail, every monday morning, when the database is opened. The problem is I can't get the reports to show the most recent data in the charts. The procedure is as follows (with Report1 as example)
(Users open a .accdr version of the database)
Upon opening this code runs when the head form loads (form_load event):
If Weekday(Now(), 2) = 1 Then
If Forms![Head Form]![Once subform].Form![ID] = 0 Then
DoCmd.OpenQuery "UpdateOnce1", acViewNormal, acEdit
DoCmd.SetWarnings False
DoCmd.OpenReport "Report1", acViewPreview
DoCmd.RunSavedImportExport "Export-Report 1"
Dim strSql
Dim db As Database
Set db = CurrentDb()
Dim Outlook
Dim rng
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = "number of mail adresses"
.CC = ""
.BCC = ""
.Subject = "Report 1"
.HTMLBody = ""
.Attachments.Add ("T:\.....\Report1.pdf")
.Send
End With
DoCmd.Close acReport, "Report1"
End If
End If
So if it is monday, and the code hasn't run yet, Report 1 is openend, exported to PDF, added as an attachment and then mailed via outlook.
As you can see I currently tried opening the reports before calling the code to mail the pdf, in hopes of refreshing it before it exports. But it doesn't seem to be working unfortunately, because the report doesn't show the most recent data.
Any ideas on how I can refresh/requery the report before it is exported & mailed? Much appreciated.
Tim
One way around it is a make table with the most recent data you want when your criteria is met (monday, not been ran yet) and base the report off that, then once you have exported the report delete the temp table with your data. This also prevents users pissing around with your queries/set up etc.
a bit like
dim ssql as string
sSql = "Select yourFields from yourTable INTO tmpTblRpt"
currentdb.execute(ssql)
'set the rpt to be based off tmptblRpt here
then set warnings off docmd.deleteObject actable, "tmpTblRpt" then warnings back on

How to schedule auto-exporting MS Access query to Excel and email it?

I know Access can setup an Outlook Task to auto-export query to Excel, but it requires the Outlook to be always open on the user's computer.
Is there an easy way to setup a schedule that can automatically export a query to Excel and this schedule will then auto-email the exported Excel file to an email address every Monday at 5AM for example?
If this can only be done in VBA, any reference I may start with?
Thanks.
I do not think you can do this with Access. You can use a tool like these:
http://www.r-tag.com
http://www.hybing.com/Report-Genie.html
They are able to get data from a database, export it to excel and email it. Report genie is cheap although it is pretty old software and I don't know if it has any support. I don't think there is a way to schedule tasks too. R-Tag has paid and free version. Both versions will allow you to schedule a task to export data from any database to excel and email the file. There are some restrictions for the free version.
I don't know how to schedule it, but this may give you a good start:
If Weekday(Now(), 2) = 1 Then
If Forms![Head Form]![Once subform].Form![ID] = 0 Then
DoCmd.OpenQuery "UpdateOnce1", acViewNormal, acEdit
DoCmd.SetWarnings False
DoCmd.OpenReport "Report1", acViewPreview
DoCmd.RunSavedImportExport "Export-Report 1"
Dim strSql
Dim db As Database
Set db = CurrentDb()
Dim Outlook
Dim rng
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = "number of mail adresses"
.CC = ""
.BCC = ""
.Subject = "Report 1"
.HTMLBody = ""
.Attachments.Add ("T:\.....\Report1.pdf")
.Send
End With
DoCmd.Close acReport, "Report1"
End If
End If
So if it is monday, and the code hasn't run yet (it checks if the ID equals 0), Report 1 is openend, exported to PDF, added as an attachment and then mailed via outlook.

Creating a 'calendar matrix' in Access

I’m trying to create either a report or form that displays data in essentially a “calendar” form.
I have a course query that is (simplified) as “Course name”; “course days”; “course times”---
Course; Days; Times
PSY 1; MW; 8A-9A
SOC 150; M; 8A-11A
ANTH 2; Tu; 8A-9A
ANTH 199; MW; 8A-9A
In Access, I’m trying to create a form based on the query that would give me a matrix of the following:
Columns: Times in hour increments
Rows: Days of week
So, for example, with the above data, it would appear like this:
Edit: Yargh, I can't submit an image unfortunately. So, here is a link to a "course schedule" that is essentially what I'm trying to do: Schedule
I have no idea where to start with this. Any tips (or links)?
Edit:
One idea I have is to create a form with a field for every possible cell in the matrix (so, for example, there would be one "Monday, 8-9A" field--and that field would be a filter on the query that ONLY displays results where "day" contains "M" and BeginTime or EndTime or between 8A and 9A). Unfortunately, I'm not sure how to do that.
You can do something close to what you seem to want as an Access form, but it's not easy. This screen capture displays your sample data in a Datasheet View form whose record source is an ADO disconnected recordset. It uses conditional formatting to set the text box background color when the text box value is not Null. Your picture suggested a different color for each Course, but I didn't want to deal with that when more than one Course can be scheduled in the same time block ... my way was simpler for me to cope with. :-)
The code to create and load the disconnected recordset is included below as GetRecordset(). The form's open event sets its recordset to GetRecordset().
Private Sub Form_Open(Cancel As Integer)
Set Me.Recordset = GetRecordset
End Sub
Note I stored your sample data differently. Here is my Class_sessions table:
Course day_of_week start_time end_time
------ ----------- ---------- -----------
PSY 1 2 8:00:00 AM 9:00:00 AM
PSY 1 4 8:00:00 AM 9:00:00 AM
SOC 150 2 8:00:00 AM 11:00:00 AM
ANTH 2 3 8:00:00 AM 9:00:00 AM
ANTH 199 2 8:00:00 AM 9:00:00 AM
ANTH 199 4 8:00:00 AM 9:00:00 AM
This is the function to create the disconnected recordset which is the critical piece for this approach. I developed this using early binding which requires a reference for "Microsoft ActiveX Data Objects [version] Library"; I used version 2.8. For production use, I would convert the code to use late binding and discard the reference. I left it as early binding so that you may use Intellisense to help you understand how it works.
Public Function GetRecordset() As Object
Dim rsAdo As ADODB.Recordset
Dim fld As ADODB.Field
Dim db As DAO.Database
Dim dteTime As Date
Dim i As Long
Dim qdf As DAO.QueryDef
Dim rsDao As DAO.Recordset
Dim strSql As String
Set rsAdo = New ADODB.Recordset
With rsAdo
.Fields.Append "start_time", adDate, , adFldKeyColumn
For i = 2 To 6
.Fields.Append WeekdayName(i), adLongVarChar, -1, adFldMayBeNull
Next
.CursorType = adOpenKeyset
.CursorLocation = adUseClient
.LockType = adLockPessimistic
.Open
End With
strSql = "PARAMETERS block_start DateTime;" & vbCrLf & _
"SELECT day_of_week, Course, start_time, end_time" & vbCrLf & _
"FROM Class_sessions" & vbCrLf & _
"WHERE [block_start] BETWEEN start_time AND end_time" & vbCrLf & _
"ORDER BY day_of_week, Course;"
Set db = CurrentDb
Set qdf = db.CreateQueryDef(vbNullString, strSql)
dteTime = #7:00:00 AM#
Do While dteTime < #6:00:00 PM#
'Debug.Print "Block start: " & dteTime
rsAdo.AddNew
rsAdo!start_time = dteTime
rsAdo.Update
qdf.Parameters("block_start") = dteTime
Set rsDao = qdf.OpenRecordset(dbOpenSnapshot)
Do While Not rsDao.EOF
'Debug.Print WeekdayName(rsDao!day_of_week), rsDao!Course
rsAdo.Fields(WeekdayName(rsDao!day_of_week)) = _
rsAdo.Fields(WeekdayName(rsDao!day_of_week)) & _
rsDao!Course & vbCrLf
rsAdo.Update
rsDao.MoveNext
Loop
dteTime = DateAdd("h", 1, dteTime)
Loop
rsDao.Close
Set rsDao = Nothing
qdf.Close
Set qdf = Nothing
Set GetRecordset = rsAdo
End Function
Actually, if you look at the following video of mine, you can see a calendar created in Access that runs inside of a browser with the new Access Web publishing feature.
http://www.youtube.com/watch?v=AU4mH0jPntI
So, all you really need to do here is format a form with text boxes and setup some code to fill them. VBA or even the above video shows this is quite easy for Access.
I doubt that you will find an easy solution for this problem in Access forms or reports.
The issue is that you need to format different cells differently, and that cells can span multiple rows and have to be merged.
If I were you, I would go in either of these 2 directions:
Drive Excel from Access, because you can format and merge cells independently
Use the Web Browser Control to display HTML that you construct yourself using tables, or a more high-level library like FullCalendar
I would be partial to tryingthe Web Browser and find the right library that can properly format the data.
I know this post is quite old, but I had the same requirement but I got round it by doing the following:
I created a module that would write HTML code (as a text file) to produce the data using a table.
I used the colspan feature of tables to enable me to dynamically produce the view I needed.
The HTML file was created on the Form_Open event and by pointing the webbrowser control to the HTML file the view shows the latest data.
A css file is used to handle the visual display of the HTML file so that it looks similar to the Access forms already in use.
If anyone is interested I can post some code to further illustrate.