[AccessD] Setting data into and getting data from Named Range s

Shamil Salakhetdinov shamil at users.mns.ru
Mon Jan 23 18:03:20 CST 2006


John,

Have a look here is a generic code to get data to ms excel worksheet
from MS Access database and to save data to MS Access db from ms excel
worksheet using disconnected ADO recordsets. This sample uses arrays
because an MS Excel range value is in fact a variant array. It shouldn't
be used with very large source recordsets but as far as I understood you
will not have such recordsets...

Private Const mcstrMdbFullPath As String = _
    "<Your sample mdb fullpath here>"
Private Const mcstrSql As String = _
   "select [CategoryID],[CategoryName],[Description] from [Categories]"
Private Const mcstrDelSql1 As String = _
   "delete * from [Categories1]"
Private Const mcstrSql1 As String = _
   "select [CategoryID],[CategoryName],[Description] from [Categories1]"
'Note: Categories1.CategoryId is assumed to be long integer not
autonumber

Public Sub Tests()
' sample code for MS Excel
Dim xlApp As Excel.Application
Dim wks As Excel.Worksheet
Dim rng As Excel.Range
    Set xlApp = Excel.Application
    Set wks = xlApp.ActiveWorkbook.Worksheets(1)
    Set rng = wks.Cells(2, 2) ' just a top left cell of a test range
    Set rng = GetRowsSample(xlApp, wks, rng)
    SaveRowsSample rng
End Sub

Public Function GetRowsSample( _
   ByRef rxlApp As Excel.Application, _
   ByRef rwks As Excel.Worksheet, _
   ByRef rrng As Excel.Range)
Dim cnn As ADODB.Connection
Dim strCnn As String
Dim rstSrc As ADODB.Recordset
Dim avarSrcValues As Variant
Dim avarSrcValuesT As Variant
Dim rng As Excel.Range

   strCnn = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
         "User ID=Admin;" & _
         "Data Source=" & mcstrMdbFullPath & ";" & _
         "Mode=Share Deny None"
   Set cnn = New ADODB.Connection
   cnn.Open strCnn
   Set rstSrc = New ADODB.Recordset
   rstSrc.Open mcstrSql, cnn, adOpenStatic, adLockOptimistic, adCmdText
   avarSrcValues = rstSrc.GetRows
   rstSrc.Close

   avarSrcValuesT = TransposeMatrixArray(avarSrcValues)
   Set rng = rwks.Range(rrng, _
             rwks.Cells(rrng.Row + UBound(avarSrcValuesT, 1), _
                       rrng.Column + UBound(avarSrcValuesT, 2)))
   rng.Value = avarSrcValuesT
   cnn.Close

   Set GetRowsSample = rng
End Function

Private Function TransposeMatrixArray(ByRef ravar As Variant) As Variant
Dim avar As Variant
Dim lngRowIdx As Long
Dim lngColIdx As Long
   ReDim avar(0 To UBound(ravar, 2), 0 To UBound(ravar, 1))

   For lngColIdx = LBound(ravar, 1) To UBound(ravar, 1)
      For lngRowIdx = LBound(ravar, 2) To UBound(ravar, 2)
         avar(lngRowIdx, lngColIdx) = ravar(lngColIdx, lngRowIdx)
      Next lngRowIdx
   Next lngColIdx

   TransposeMatrixArray = avar
End Function

Public Function SaveRowsSample(ByRef rrng As Excel.Range)
Dim cnn As ADODB.Connection
Dim strCnn As String
Dim rstDst As ADODB.Recordset
Dim lngIdx As Long
Dim lngRowIdx As Long
Dim lngColIdx As Long
Dim avarSrcValues As Variant
Dim avarNames As Variant
Dim avarValues As Variant

   strCnn = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
         "User ID=Admin;" & _
         "Data Source=" & mcstrMdbFullPath & ";" & _
         "Mode=Share Deny None"
   Set cnn = New ADODB.Connection
   cnn.Open strCnn
   cnn.Execute mcstrDelSql1
   Set rstDst = New ADODB.Recordset
   With rstDst
      .CursorLocation = adUseClient
      .Open mcstrSql1, cnn, adOpenStatic, adLockBatchOptimistic,
adCmdText
      Set .ActiveConnection = Nothing
   End With

   avarSrcValues = rrng.Value
   ReDim avarNames(0 To rstDst.Fields.Count - 1)
   ReDim avarValues(0 To rstDst.Fields.Count - 1)

   For lngIdx = 0 To rstDst.Fields.Count - 1
      avarNames(lngIdx) = rstDst.Fields(lngIdx).Name
   Next lngIdx

   For lngRowIdx = 1 To rrng.Rows.Count
        For lngIdx = 0 To rstDst.Fields.Count - 1
           avarValues(lngIdx) = avarSrcValues(lngRowIdx, lngIdx + 1)
        Next lngIdx
        rstDst.AddNew avarNames, avarValues
   Next lngRowIdx

   Set rstDst.ActiveConnection = cnn
   rstDst.UpdateBatch

   rstDst.Close
   cnn.Close
End Function

BTW,  if you'll find your customer wants a lot but doesn't have enough
resources then you may consider to use these 4TOPS Add-ns:

- 4TOPS Excel Link(http://www.4tops.com/excel_link.htm) - to export data
into MS Excel templates and to send these data;
- 4TOPS Excel Import Assistant (http://www.4tops.com/excelimport.htm) -
to import excel worksheets' data into MS Access databases
and even maybe 4TOPS Document Mangement
(http://www.4tops.com/downloaddocumentmanagement.htm).

These are stable software products and they were used in real life large
apps (one of them replaced big Oracle based app).
They are rather generic to fit your current customer tasks but of course
they may have limitations, which will not let you to use them.
And they export data from/import data to normalized databases. Useful
feature and implemented generic way.
They can be used as Add-ins by powerusers and even "weak"users.
They have simple APIs for developers and can be used as library
databases. (One test was to import 3000 MS Excel workbooks with several
worksheets with many source rows in one run - it worked well and it
would work well more - no memory leakage etc. problems - well tested -
and that's is so time consuming activity...)

BTW, when importing data from MS Excel worksheet forms, maybe having
additionally several "subforms", you may consider to create in your
templates special additional "worksheet(s) records reference
templates" - every cell of these templates rows' will have a reference
to the actual value of worksheet form/subform - then you will not need
to use named ranges to get data imported piece by piece (cell by cell -
it's slow) - you will be able to get whole source ranges' values at
once....

etc.

Shamil

----- Original Message ----- 
From: "John Colby" <jwcolby at ColbyConsulting.com>
To: "'Access Developers discussion and problem solving'"
<accessd at databaseadvisors.com>
Sent: Monday, January 23, 2006 11:40 PM
Subject: Re: [AccessD] Setting data into and getting data from Named
Range s


> Jim,
>
> I did, and thanks for the offer.  I think that understanding that it
is the
> range object that actually does the work kind of removed my mental
> roadblocks.  I was thinking that the name object should have abilities
that
> it doesn't have.  I sent an email re "success" to the group.
>
> Again, thanks for the offer.  If I run into any more roadblocks I will
keep
> you in mind.  Kind of the last piece for right now is reading data
back out
> of a named range.  I have code for doing that, though it is kind of
rough
> ATM.
>
> This is for a client who is documenting construction of a hospital.
> Apparently federal law requires that they collect documents for each
and
> every one of certain kinds of systems, paper and electronic, and store
them.
> My client did not understand the size of the job when he got involved,
nor
> when he got me involved.
>
> I am of course building a database to track all of the documents,
request
> them (electronically) from each contractor (via this Request For
Document
> spreadsheet, attached to emails) for each document, then as the
electronic
> documents are returned via attachments to the email I send, strip the
> attachments off and file them in an intricate directory structure out
on the
> hard disk.  There will be literally thousands of documents, perhaps
tens of
> thousands.  6 contractors, 91 systems (though some are "copies", i.e.
7 "Air
> handling units"), and ~150 documents, although all docs are not
required for
> all systems.  My db has to track what has been requested, store
"proof" that
> we did request them (each Excel RFD is saved in the same directory
> structure), track which docs are received back, report which docs are
"owed"
> by which contractors for which systems, and report which system's
documents
> have been completely received.
>
> We are trying to convince all the contractors to work with us in
naming the
> documents to a standard so that as the attachments come in I can parse
the
> doc name to see what system/document it is and "count it as received".
> There are just so many documents that to do this stuff manually would
invite
> chaos.
>
> On top of all that, the requirement is for both paper copies as well
as
> electronic copies, so the db has to track both.  My client has to make
paper
> copies from Electronics where no paper exists, and make electronic
from
> paper where no electronic exist, and get it all entered in the db each
time.
>
> And finally, the main company (Pfizer) in charge of construction, had
the
> unfortunate experience of having their paper copies burned to the
ground one
> time.  As a result I also have to ensure that the electronic copies
get
> automatically written to a local and offsite location, which I will be
doing
> via high speed internet.  I have to track that each electronic
document gets
> written to the back up location as well - a usb hard disk on a
computer
> somewhere out on the internet.  Since the internet can be unavailable,
I
> have to handle that as well, performing the write when the internet
becomes
> available.
>
> The paper in this case will completely fill a single wide trailer when
all
> is said and done, and in fact they have a single wide trailer that
they are
> using to collect the paper.  When they are done they will hook up a
truck
> and haul the paper... Somewhere... Hopefully fireproof.  ;-)
>
> This is where "time and expenses" really takes on meaning!  I quoted
40
> hours to do what my client originally asked for - and DELIVERED that.
Of
> course my client did not understand the scope and so we soldier on.
>
> John W. Colby
> www.ColbyConsulting.com
>
>
> -----Original Message-----
> From: accessd-bounces at databaseadvisors.com
> [mailto:accessd-bounces at databaseadvisors.com] On Behalf Of Hale, Jim
> Sent: Monday, January 23, 2006 1:45 PM
> To: 'Access Developers discussion and problem solving'
> Subject: Re: [AccessD] Setting data into and getting data from Named
Range s
>
> John,
> I sent you an email, did you get it?
> Jim Hale
>
> -- 
> AccessD mailing list
> AccessD at databaseadvisors.com
> http://databaseadvisors.com/mailman/listinfo/accessd
> Website: http://www.databaseadvisors.com




More information about the AccessD mailing list