Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 48
Default Ideas for quicker way to populate adjacent cells with array elemen

Hi,

I written a macro to read in line by line multiple CSV files of varying
lengths.

Can anyone suggest a faster way in terms of runtime execution time to speed
this code up?

ie. I thought of reading in multiple lines in bulk to reduce I/O but VBA
doesn't seem to have a bulk read mode.

Basically i do the following:

Dim columnArrays as Variant
Dim newColumnArray as Variant
..
..
Do until EOF(inputFile)
Line Input #inputFile, inputLine
columnArray = Split(inputLine, ",")
....merge/massage/apply functions to certain columns in columnArray
and copy into newColumnArray
for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i
set aRnage = aRange.Offset(1,0)
Loop

Thanks to everyone for their valuable insights.
  #2   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 1,758
Default Ideas for quicker way to populate adjacent cells with array elemen

Is there a reason you couldn't just use:
workbooks.open filename:="C:\myfolder\inputname.csv"

If you want more control of individual field formats, rename your .csv file to
..txt and then record a macro when you do file|open.

I would think that opening multiple files this way (and combining later) would
be quicker (even noticeable when the number of lines gets larger).

Another option would be to use an old DOS command to combine your .csv files
into a single file, then import that once.

If the files are in the same folder and all files named *.csv should be
combined:

Shell to DOS
traverse to that folder
copy *.csv all.txt
Then exit the command prompt.

Back to excel and import All.Txt.

===
You could even mechanize this in your code via the shell command (and maybe an
application.wait to make sure the files are combined before continuing).





Bing wrote:

Hi,

I written a macro to read in line by line multiple CSV files of varying
lengths.

Can anyone suggest a faster way in terms of runtime execution time to speed
this code up?

ie. I thought of reading in multiple lines in bulk to reduce I/O but VBA
doesn't seem to have a bulk read mode.

Basically i do the following:

Dim columnArrays as Variant
Dim newColumnArray as Variant
.
.
Do until EOF(inputFile)
Line Input #inputFile, inputLine
columnArray = Split(inputLine, ",")
....merge/massage/apply functions to certain columns in columnArray
and copy into newColumnArray
for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i
set aRnage = aRange.Offset(1,0)
Loop

Thanks to everyone for their valuable insights.


--

Dave Peterson
  #3   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 48
Default Ideas for quicker way to populate adjacent cells with array el

Hi Dave,

Thanks for responding.

The reason why i didn't use workbooks.open or workbooks.opentext is because
of several reasons:

1)Some files are much more than 65K lines. Since excel has a limit of 65536,
i need to import the file across multiple worksheets.
2)Yes, i wanted more control. Although i haven't actually tested to
determine which method is faster (ie. using workbooks.open first, and then
combining the columns later versus using Line Input, combining columns first,
then pasting to worksheet later) my gut feeling would be that the former is
quicker in loading lines into workbook, but the latter would be quicker in
combining the columns). But i think you may be right that as the number of
lines increase it would be quicker using the workbooks.open first, combine
later. But due to 1) i can't seem to find a alternative to doing the way
that i had outlined earliar (reading in manually line by line so that i can
add a new worksheets in the even the number of lines is 64K).

This application is being developed for customers so i'd like to minimize
steps that they have to perform. ie. i dont want them to have to separate
the large file into individual 64K line subfiles.

"Dave Peterson" wrote:

Is there a reason you couldn't just use:
workbooks.open filename:="C:\myfolder\inputname.csv"

If you want more control of individual field formats, rename your .csv file to
..txt and then record a macro when you do file|open.

I would think that opening multiple files this way (and combining later) would
be quicker (even noticeable when the number of lines gets larger).

Another option would be to use an old DOS command to combine your .csv files
into a single file, then import that once.

If the files are in the same folder and all files named *.csv should be
combined:

Shell to DOS
traverse to that folder
copy *.csv all.txt
Then exit the command prompt.

Back to excel and import All.Txt.

===
You could even mechanize this in your code via the shell command (and maybe an
application.wait to make sure the files are combined before continuing).





Bing wrote:

Hi,

I written a macro to read in line by line multiple CSV files of varying
lengths.

Can anyone suggest a faster way in terms of runtime execution time to speed
this code up?

ie. I thought of reading in multiple lines in bulk to reduce I/O but VBA
doesn't seem to have a bulk read mode.

Basically i do the following:

Dim columnArrays as Variant
Dim newColumnArray as Variant
.
.
Do until EOF(inputFile)
Line Input #inputFile, inputLine
columnArray = Split(inputLine, ",")
....merge/massage/apply functions to certain columns in columnArray
and copy into newColumnArray
for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i
set aRnage = aRange.Offset(1,0)
Loop

Thanks to everyone for their valuable insights.


--

Dave Peterson

  #4   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 1,758
Default Ideas for quicker way to populate adjacent cells with array el

First, excel may not be the best application for this amount of data.

I notice that excel starts to slow down considerably when I have lots of rows of
data (no formulas even).

I don't use Access (and maybe your customers don't either), but have you thought
of using a different application.





Bing wrote:

Hi Dave,

Thanks for responding.

The reason why i didn't use workbooks.open or workbooks.opentext is because
of several reasons:

1)Some files are much more than 65K lines. Since excel has a limit of 65536,
i need to import the file across multiple worksheets.
2)Yes, i wanted more control. Although i haven't actually tested to
determine which method is faster (ie. using workbooks.open first, and then
combining the columns later versus using Line Input, combining columns first,
then pasting to worksheet later) my gut feeling would be that the former is
quicker in loading lines into workbook, but the latter would be quicker in
combining the columns). But i think you may be right that as the number of
lines increase it would be quicker using the workbooks.open first, combine
later. But due to 1) i can't seem to find a alternative to doing the way
that i had outlined earliar (reading in manually line by line so that i can
add a new worksheets in the even the number of lines is 64K).

This application is being developed for customers so i'd like to minimize
steps that they have to perform. ie. i dont want them to have to separate
the large file into individual 64K line subfiles.

"Dave Peterson" wrote:

Is there a reason you couldn't just use:
workbooks.open filename:="C:\myfolder\inputname.csv"

If you want more control of individual field formats, rename your .csv file to
..txt and then record a macro when you do file|open.

I would think that opening multiple files this way (and combining later) would
be quicker (even noticeable when the number of lines gets larger).

Another option would be to use an old DOS command to combine your .csv files
into a single file, then import that once.

If the files are in the same folder and all files named *.csv should be
combined:

Shell to DOS
traverse to that folder
copy *.csv all.txt
Then exit the command prompt.

Back to excel and import All.Txt.

===
You could even mechanize this in your code via the shell command (and maybe an
application.wait to make sure the files are combined before continuing).





Bing wrote:

Hi,

I written a macro to read in line by line multiple CSV files of varying
lengths.

Can anyone suggest a faster way in terms of runtime execution time to speed
this code up?

ie. I thought of reading in multiple lines in bulk to reduce I/O but VBA
doesn't seem to have a bulk read mode.

Basically i do the following:

Dim columnArrays as Variant
Dim newColumnArray as Variant
.
.
Do until EOF(inputFile)
Line Input #inputFile, inputLine
columnArray = Split(inputLine, ",")
....merge/massage/apply functions to certain columns in columnArray
and copy into newColumnArray
for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i
set aRnage = aRange.Offset(1,0)
Loop

Thanks to everyone for their valuable insights.


--

Dave Peterson


--

Dave Peterson
  #5   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 339
Default Ideas for quicker way to populate adjacent cells with array elemen


"Bing" wrote in message
...
Hi,

I written a macro to read in line by line multiple CSV files of varying
lengths.

Can anyone suggest a faster way in terms of runtime execution time to

speed
this code up?

ie. I thought of reading in multiple lines in bulk to reduce I/O but VBA
doesn't seem to have a bulk read mode.

Basically i do the following:

Dim columnArrays as Variant
Dim newColumnArray as Variant
.
.
Do until EOF(inputFile)
Line Input #inputFile, inputLine
columnArray = Split(inputLine, ",")
....merge/massage/apply functions to certain columns in columnArray
and copy into newColumnArray
for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i
set aRnage = aRange.Offset(1,0)
Loop

Thanks to everyone for their valuable insights.


You do call Application.ScreenUpdate=False, I hope?

/ Fredrik




  #6   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 74
Default Ideas for quicker way to populate adjacent cells with array elemen

Bing wrote:
I written a macro to read in line by line multiple CSV files of

varying
lengths.

Can anyone suggest a faster way in terms of runtime execution time to

speed
this code up?


See:

http://msdn.microsoft.com/library/de...ng03092004.asp
Jamie.

--

  #7   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 48
Default Ideas for quicker way to populate adjacent cells with array el

Hi Jamie,

Interesting. Do you know what version of Excel is required for this
particular methodogly, and what sort of libraries neet to be installed? (ie.
it look like Microsoft Jet has to be installed as the "database" driver")

Also,do you have any ideas how fast a query using ADO on a very large file
to do things like subtotaling compared to writing vba code to parse same data
to do the subtotaling?

Thanks

"onedaywhen" wrote:

Bing wrote:
I written a macro to read in line by line multiple CSV files of

varying
lengths.

Can anyone suggest a faster way in terms of runtime execution time to

speed
this code up?


See:

http://msdn.microsoft.com/library/de...ng03092004.asp
Jamie.

--


  #8   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 48
Default Ideas for quicker way to populate adjacent cells with array el

Hi Vic,

Thanks i tried it.. i got an almost 6x speed improvement. Only 1 thing..
this operation seems to automatically convert numbers as text. So rather
than have to call aRange.PasteSpecial to convert from text back to numbers,
is there a way to do this so that the resize operation treats the data as is,
without converting to text.

Thanks again.

"Vic Eldridge" wrote:

Hi Bing,

Firstly, try replacing the following code ,

for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i


with this...

aRange.Resize(, UBound(newColumnArray) + 1) = newColumnArray


What this does is transfer the whole array to the worksheet in one fell
swoop, as opposed to transferring each element one by one. The speed gain
comes from the fact that your calls to Excel's slow Range object are reduced
from multiple calls, to a single call.
Now take this concept a little further. Instead of creating a 1-dimensional
array of each and every row, then transferring each row separately, you
should create a 2-dimensional array of all rows and columns, and transfer the
whole
array in one hit after EOF has been reached.

You'll be removing hundreds of thousands of calls to the Range object.
You're in for a nice surprise. It's gonna fly !


Regards,
Vic Eldridge



"Bing" wrote:

Hi,

I written a macro to read in line by line multiple CSV files of varying
lengths.

Can anyone suggest a faster way in terms of runtime execution time to speed
this code up?

ie. I thought of reading in multiple lines in bulk to reduce I/O but VBA
doesn't seem to have a bulk read mode.

Basically i do the following:

Dim columnArrays as Variant
Dim newColumnArray as Variant
.
.
Do until EOF(inputFile)
Line Input #inputFile, inputLine
columnArray = Split(inputLine, ",")
....merge/massage/apply functions to certain columns in columnArray
and copy into newColumnArray
for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i
set aRnage = aRange.Offset(1,0)
Loop

Thanks to everyone for their valuable insights.

  #9   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 112
Default Ideas for quicker way to populate adjacent cells with array el

Hi Bing,

The only way I could get this process to convert from values to text was to
dimension the array as String. Arrays dimmed as Longs,Doubles,Variants all
transferred to the worksheet as values. Is that where the problem lies ?


Regards,
Vic Eldridge


"Bing" wrote:

Hi Vic,

Thanks i tried it.. i got an almost 6x speed improvement. Only 1 thing..
this operation seems to automatically convert numbers as text. So rather
than have to call aRange.PasteSpecial to convert from text back to numbers,
is there a way to do this so that the resize operation treats the data as is,
without converting to text.

Thanks again.

"Vic Eldridge" wrote:

Hi Bing,

Firstly, try replacing the following code ,

for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i


with this...

aRange.Resize(, UBound(newColumnArray) + 1) = newColumnArray


What this does is transfer the whole array to the worksheet in one fell
swoop, as opposed to transferring each element one by one. The speed gain
comes from the fact that your calls to Excel's slow Range object are reduced
from multiple calls, to a single call.
Now take this concept a little further. Instead of creating a 1-dimensional
array of each and every row, then transferring each row separately, you
should create a 2-dimensional array of all rows and columns, and transfer the
whole
array in one hit after EOF has been reached.

You'll be removing hundreds of thousands of calls to the Range object.
You're in for a nice surprise. It's gonna fly !


Regards,
Vic Eldridge



"Bing" wrote:

Hi,

I written a macro to read in line by line multiple CSV files of varying
lengths.

Can anyone suggest a faster way in terms of runtime execution time to speed
this code up?

ie. I thought of reading in multiple lines in bulk to reduce I/O but VBA
doesn't seem to have a bulk read mode.

Basically i do the following:

Dim columnArrays as Variant
Dim newColumnArray as Variant
.
.
Do until EOF(inputFile)
Line Input #inputFile, inputLine
columnArray = Split(inputLine, ",")
....merge/massage/apply functions to certain columns in columnArray
and copy into newColumnArray
for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i
set aRnage = aRange.Offset(1,0)
Loop

Thanks to everyone for their valuable insights.

  #10   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 48
Default Ideas for quicker way to populate adjacent cells with array el

Hi Vic,

The array is defined as variants, with some elements being integer values,
other's are string literals.

So when i do the resize, the problem is the resize converts all integer
values to text ie. 8 becomes "8". And hence, i can't perform any
mathematical operations on cell contents until i convert the cell contents
back into integer values.

I tried using the PasteSpecial method to convert back to integer but doing
this really slows everything back down to a crawl again.


"Vic Eldridge" wrote:

Hi Bing,

The only way I could get this process to convert from values to text was to
dimension the array as String. Arrays dimmed as Longs,Doubles,Variants all
transferred to the worksheet as values. Is that where the problem lies ?


Regards,
Vic Eldridge


"Bing" wrote:

Hi Vic,

Thanks i tried it.. i got an almost 6x speed improvement. Only 1 thing..
this operation seems to automatically convert numbers as text. So rather
than have to call aRange.PasteSpecial to convert from text back to numbers,
is there a way to do this so that the resize operation treats the data as is,
without converting to text.

Thanks again.

"Vic Eldridge" wrote:

Hi Bing,

Firstly, try replacing the following code ,

for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i

with this...

aRange.Resize(, UBound(newColumnArray) + 1) = newColumnArray


What this does is transfer the whole array to the worksheet in one fell
swoop, as opposed to transferring each element one by one. The speed gain
comes from the fact that your calls to Excel's slow Range object are reduced
from multiple calls, to a single call.
Now take this concept a little further. Instead of creating a 1-dimensional
array of each and every row, then transferring each row separately, you
should create a 2-dimensional array of all rows and columns, and transfer the
whole
array in one hit after EOF has been reached.

You'll be removing hundreds of thousands of calls to the Range object.
You're in for a nice surprise. It's gonna fly !


Regards,
Vic Eldridge



"Bing" wrote:

Hi,

I written a macro to read in line by line multiple CSV files of varying
lengths.

Can anyone suggest a faster way in terms of runtime execution time to speed
this code up?

ie. I thought of reading in multiple lines in bulk to reduce I/O but VBA
doesn't seem to have a bulk read mode.

Basically i do the following:

Dim columnArrays as Variant
Dim newColumnArray as Variant
.
.
Do until EOF(inputFile)
Line Input #inputFile, inputLine
columnArray = Split(inputLine, ",")
....merge/massage/apply functions to certain columns in columnArray
and copy into newColumnArray
for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i
set aRnage = aRange.Offset(1,0)
Loop

Thanks to everyone for their valuable insights.



  #11   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 48
Default Ideas for quicker way to populate adjacent cells with array el

Hi Vic,

Wasn't too sure what you meant when you said "only way I(you) could get his
process to convert from values to text".... in my case, i don't want to
convert to text, but want to remain as values (ie. integers) in the cells so
i can do mathematical formulas on them.

"Vic Eldridge" wrote:

Hi Bing,

The only way I could get this process to convert from values to text was to
dimension the array as String. Arrays dimmed as Longs,Doubles,Variants all
transferred to the worksheet as values. Is that where the problem lies ?


Regards,
Vic Eldridge


"Bing" wrote:

Hi Vic,

Thanks i tried it.. i got an almost 6x speed improvement. Only 1 thing..
this operation seems to automatically convert numbers as text. So rather
than have to call aRange.PasteSpecial to convert from text back to numbers,
is there a way to do this so that the resize operation treats the data as is,
without converting to text.

Thanks again.

"Vic Eldridge" wrote:

Hi Bing,

Firstly, try replacing the following code ,

for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i

with this...

aRange.Resize(, UBound(newColumnArray) + 1) = newColumnArray


What this does is transfer the whole array to the worksheet in one fell
swoop, as opposed to transferring each element one by one. The speed gain
comes from the fact that your calls to Excel's slow Range object are reduced
from multiple calls, to a single call.
Now take this concept a little further. Instead of creating a 1-dimensional
array of each and every row, then transferring each row separately, you
should create a 2-dimensional array of all rows and columns, and transfer the
whole
array in one hit after EOF has been reached.

You'll be removing hundreds of thousands of calls to the Range object.
You're in for a nice surprise. It's gonna fly !


Regards,
Vic Eldridge



"Bing" wrote:

Hi,

I written a macro to read in line by line multiple CSV files of varying
lengths.

Can anyone suggest a faster way in terms of runtime execution time to speed
this code up?

ie. I thought of reading in multiple lines in bulk to reduce I/O but VBA
doesn't seem to have a bulk read mode.

Basically i do the following:

Dim columnArrays as Variant
Dim newColumnArray as Variant
.
.
Do until EOF(inputFile)
Line Input #inputFile, inputLine
columnArray = Split(inputLine, ",")
....merge/massage/apply functions to certain columns in columnArray
and copy into newColumnArray
for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i
set aRnage = aRange.Offset(1,0)
Loop

Thanks to everyone for their valuable insights.

  #12   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 48
Default Ideas for quicker way to populate adjacent cells with array el

Ok, i got you know.. i think i know where the problem lies.

Dim columns as Variant
columns = split(inputString, ",") <- i think this returns an array of strings.
range.resize(,UBound(columns)+1) = columns <- puts in text in the cells

I think i need to keepthe columns array as, like you said, as variant.

Guess i have to use some other method other than split?

"Vic Eldridge" wrote:

Hi Bing,

The only way I could get this process to convert from values to text was to
dimension the array as String. Arrays dimmed as Longs,Doubles,Variants all
transferred to the worksheet as values. Is that where the problem lies ?


Regards,
Vic Eldridge


"Bing" wrote:

Hi Vic,

Thanks i tried it.. i got an almost 6x speed improvement. Only 1 thing..
this operation seems to automatically convert numbers as text. So rather
than have to call aRange.PasteSpecial to convert from text back to numbers,
is there a way to do this so that the resize operation treats the data as is,
without converting to text.

Thanks again.

"Vic Eldridge" wrote:

Hi Bing,

Firstly, try replacing the following code ,

for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i

with this...

aRange.Resize(, UBound(newColumnArray) + 1) = newColumnArray


What this does is transfer the whole array to the worksheet in one fell
swoop, as opposed to transferring each element one by one. The speed gain
comes from the fact that your calls to Excel's slow Range object are reduced
from multiple calls, to a single call.
Now take this concept a little further. Instead of creating a 1-dimensional
array of each and every row, then transferring each row separately, you
should create a 2-dimensional array of all rows and columns, and transfer the
whole
array in one hit after EOF has been reached.

You'll be removing hundreds of thousands of calls to the Range object.
You're in for a nice surprise. It's gonna fly !


Regards,
Vic Eldridge



"Bing" wrote:

Hi,

I written a macro to read in line by line multiple CSV files of varying
lengths.

Can anyone suggest a faster way in terms of runtime execution time to speed
this code up?

ie. I thought of reading in multiple lines in bulk to reduce I/O but VBA
doesn't seem to have a bulk read mode.

Basically i do the following:

Dim columnArrays as Variant
Dim newColumnArray as Variant
.
.
Do until EOF(inputFile)
Line Input #inputFile, inputLine
columnArray = Split(inputLine, ",")
....merge/massage/apply functions to certain columns in columnArray
and copy into newColumnArray
for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i
set aRnage = aRange.Offset(1,0)
Loop

Thanks to everyone for their valuable insights.

  #13   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 112
Default Ideas for quicker way to populate adjacent cells with array el

Guess i have to use some other method other than split?

I believe so. It appears Split() will only ever return an array of strings.
Here's a Split-free example to have a play with.

Sub ArrayToWorksheet()

Dim InputString As String
Dim vArray(1 To 4) As Variant
Dim Comma1 As Long
Dim Comma2 As Long
Dim Comma3 As Long

InputString = "1,Two,3,Four"

Comma1 = InStr(1, InputString, ",")
Comma2 = InStr(Comma1 + 1, InputString, ",")
Comma3 = InStr(Comma2 + 1, InputString, ",")

vArray(1) = Mid(InputString, 1, Comma1 - 1)
vArray(2) = Mid(InputString, Comma1 + 1, Comma2 - Comma1 - 1)
vArray(3) = Mid(InputString, Comma2 + 1, Comma3 - Comma2 - 1)
vArray(4) = Mid(InputString, Comma3 + 1)

Range("A1:D1") = vArray

End Sub




"Bing" wrote:

Ok, i got you know.. i think i know where the problem lies.

Dim columns as Variant
columns = split(inputString, ",") <- i think this returns an array of strings.
range.resize(,UBound(columns)+1) = columns <- puts in text in the cells

I think i need to keepthe columns array as, like you said, as variant.

Guess i have to use some other method other than split?

"Vic Eldridge" wrote:

Hi Bing,

The only way I could get this process to convert from values to text was to
dimension the array as String. Arrays dimmed as Longs,Doubles,Variants all
transferred to the worksheet as values. Is that where the problem lies ?


Regards,
Vic Eldridge


"Bing" wrote:

Hi Vic,

Thanks i tried it.. i got an almost 6x speed improvement. Only 1 thing..
this operation seems to automatically convert numbers as text. So rather
than have to call aRange.PasteSpecial to convert from text back to numbers,
is there a way to do this so that the resize operation treats the data as is,
without converting to text.

Thanks again.

"Vic Eldridge" wrote:

Hi Bing,

Firstly, try replacing the following code ,

for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i

with this...

aRange.Resize(, UBound(newColumnArray) + 1) = newColumnArray


What this does is transfer the whole array to the worksheet in one fell
swoop, as opposed to transferring each element one by one. The speed gain
comes from the fact that your calls to Excel's slow Range object are reduced
from multiple calls, to a single call.
Now take this concept a little further. Instead of creating a 1-dimensional
array of each and every row, then transferring each row separately, you
should create a 2-dimensional array of all rows and columns, and transfer the
whole
array in one hit after EOF has been reached.

You'll be removing hundreds of thousands of calls to the Range object.
You're in for a nice surprise. It's gonna fly !


Regards,
Vic Eldridge



"Bing" wrote:

Hi,

I written a macro to read in line by line multiple CSV files of varying
lengths.

Can anyone suggest a faster way in terms of runtime execution time to speed
this code up?

ie. I thought of reading in multiple lines in bulk to reduce I/O but VBA
doesn't seem to have a bulk read mode.

Basically i do the following:

Dim columnArrays as Variant
Dim newColumnArray as Variant
.
.
Do until EOF(inputFile)
Line Input #inputFile, inputLine
columnArray = Split(inputLine, ",")
....merge/massage/apply functions to certain columns in columnArray
and copy into newColumnArray
for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i
set aRnage = aRange.Offset(1,0)
Loop

Thanks to everyone for their valuable insights.

  #14   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 48
Default Ideas for quicker way to populate adjacent cells with array el

HI Vic,

Eureka! Works great now.. Get a tremendous speed improvement by a factor
of 5... it could even be faster but i do alot of massaging of the data before
resizing.

Thanks for your help buddy! How did you find out that you can resize a
range by using the range as an L-Value with an array as the R-Value. Of all
the documentation i've read, i have not seen reference to this.?

Thanks to all for their input as well!

"Vic Eldridge" wrote:

Guess i have to use some other method other than split?


I believe so. It appears Split() will only ever return an array of strings.
Here's a Split-free example to have a play with.

Sub ArrayToWorksheet()

Dim InputString As String
Dim vArray(1 To 4) As Variant
Dim Comma1 As Long
Dim Comma2 As Long
Dim Comma3 As Long

InputString = "1,Two,3,Four"

Comma1 = InStr(1, InputString, ",")
Comma2 = InStr(Comma1 + 1, InputString, ",")
Comma3 = InStr(Comma2 + 1, InputString, ",")

vArray(1) = Mid(InputString, 1, Comma1 - 1)
vArray(2) = Mid(InputString, Comma1 + 1, Comma2 - Comma1 - 1)
vArray(3) = Mid(InputString, Comma2 + 1, Comma3 - Comma2 - 1)
vArray(4) = Mid(InputString, Comma3 + 1)

Range("A1:D1") = vArray

End Sub




"Bing" wrote:

Ok, i got you know.. i think i know where the problem lies.

Dim columns as Variant
columns = split(inputString, ",") <- i think this returns an array of strings.
range.resize(,UBound(columns)+1) = columns <- puts in text in the cells

I think i need to keepthe columns array as, like you said, as variant.

Guess i have to use some other method other than split?

"Vic Eldridge" wrote:

Hi Bing,

The only way I could get this process to convert from values to text was to
dimension the array as String. Arrays dimmed as Longs,Doubles,Variants all
transferred to the worksheet as values. Is that where the problem lies ?


Regards,
Vic Eldridge


"Bing" wrote:

Hi Vic,

Thanks i tried it.. i got an almost 6x speed improvement. Only 1 thing..
this operation seems to automatically convert numbers as text. So rather
than have to call aRange.PasteSpecial to convert from text back to numbers,
is there a way to do this so that the resize operation treats the data as is,
without converting to text.

Thanks again.

"Vic Eldridge" wrote:

Hi Bing,

Firstly, try replacing the following code ,

for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i

with this...

aRange.Resize(, UBound(newColumnArray) + 1) = newColumnArray


What this does is transfer the whole array to the worksheet in one fell
swoop, as opposed to transferring each element one by one. The speed gain
comes from the fact that your calls to Excel's slow Range object are reduced
from multiple calls, to a single call.
Now take this concept a little further. Instead of creating a 1-dimensional
array of each and every row, then transferring each row separately, you
should create a 2-dimensional array of all rows and columns, and transfer the
whole
array in one hit after EOF has been reached.

You'll be removing hundreds of thousands of calls to the Range object.
You're in for a nice surprise. It's gonna fly !


Regards,
Vic Eldridge



"Bing" wrote:

Hi,

I written a macro to read in line by line multiple CSV files of varying
lengths.

Can anyone suggest a faster way in terms of runtime execution time to speed
this code up?

ie. I thought of reading in multiple lines in bulk to reduce I/O but VBA
doesn't seem to have a bulk read mode.

Basically i do the following:

Dim columnArrays as Variant
Dim newColumnArray as Variant
.
.
Do until EOF(inputFile)
Line Input #inputFile, inputLine
columnArray = Split(inputLine, ",")
....merge/massage/apply functions to certain columns in columnArray
and copy into newColumnArray
for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i
set aRnage = aRange.Offset(1,0)
Loop

Thanks to everyone for their valuable insights.

  #15   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 74
Default Ideas for quicker way to populate adjacent cells with array el


Bing wrote:
Do you know what version of Excel is required for this
particular methodogly, and what sort of libraries neet to be

installed? (ie.
it look like Microsoft Jet has to be installed as the "database"

driver")

Jet 4.0 SP8 can be downloaded:

http://support.microsoft.com/default...b;en-us;829558

AFAIK this includes all the files needed to use Jet e.g. the OLE DB
providers for Jet.

ADO ships with MDAC and MDAC 2.8 is also a Microsoft download
(redistributable available):

http://www.microsoft.com/downloads/d...DisplayLang=en

However, it is likely MDAC and Jet is available to you. MDAC ships with
Windows (but don't ask me which version with which version). To the
best of my knowledge, Jet 4.0 ships with Office/Excel version 2000 and
above, Jet 3.51 with Excel95 and Excel95. Jet (including the OLE DB
providers) formerly shipped with MDAC but was removed effective from
MDAC 2.6.

do you have any ideas how fast a query using ADO on a very large file


to do things like subtotaling compared to writing vba code to parse

same data
to do the subtotaling?


This sort of thing is what SQL was invented to do! My experience is
that using ADO and SQL to do such work can be orders of magnitude
faster than doing the same using procedural code. However, your data
must be suitable e.g. text files often do not have a consistent format,
data typing can be problematic, etc. Also, some text manipulations
(e.g. extracting a substring) can be hard to define using SQL alone, so
you may need some post-query processing.

Jamie.

--



  #16   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 112
Default Ideas for quicker way to populate adjacent cells with array el


Eureka! Works great now.. Get a tremendous speed improvement by a factor
of 5... it could even be faster but i do alot of massaging of the data before
resizing.


Glad it worked out for you. Just remember, when your'e looping so many times
it's important to try and avoid the use of relatively slow objects/methods
such as
Range, Cells, Offset (anything that either requires or returns a Range
object).

If you still need more speed then you would probably have to redesign your app
around a proper database management system. As Jamie mentioned, handling
large amounts of data is exactly what they're designed to do.



How did you find out that you can resize a range by using the range as...


Same way you did. If I remember rightly it was Alan "Array" Beban who
enlightened me to the technique a number of years ago. Thanks again Alan !


Regards,
Vic Eldridge


"Bing" wrote:

HI Vic,

Eureka! Works great now.. Get a tremendous speed improvement by a factor
of 5... it could even be faster but i do alot of massaging of the data before
resizing.

Thanks for your help buddy! How did you find out that you can resize a
range by using the range as an L-Value with an array as the R-Value. Of all
the documentation i've read, i have not seen reference to this.?

Thanks to all for their input as well!

"Vic Eldridge" wrote:

Guess i have to use some other method other than split?


I believe so. It appears Split() will only ever return an array of strings.
Here's a Split-free example to have a play with.

Sub ArrayToWorksheet()

Dim InputString As String
Dim vArray(1 To 4) As Variant
Dim Comma1 As Long
Dim Comma2 As Long
Dim Comma3 As Long

InputString = "1,Two,3,Four"

Comma1 = InStr(1, InputString, ",")
Comma2 = InStr(Comma1 + 1, InputString, ",")
Comma3 = InStr(Comma2 + 1, InputString, ",")

vArray(1) = Mid(InputString, 1, Comma1 - 1)
vArray(2) = Mid(InputString, Comma1 + 1, Comma2 - Comma1 - 1)
vArray(3) = Mid(InputString, Comma2 + 1, Comma3 - Comma2 - 1)
vArray(4) = Mid(InputString, Comma3 + 1)

Range("A1:D1") = vArray

End Sub




"Bing" wrote:

Ok, i got you know.. i think i know where the problem lies.

Dim columns as Variant
columns = split(inputString, ",") <- i think this returns an array of strings.
range.resize(,UBound(columns)+1) = columns <- puts in text in the cells

I think i need to keepthe columns array as, like you said, as variant.

Guess i have to use some other method other than split?

"Vic Eldridge" wrote:

Hi Bing,

The only way I could get this process to convert from values to text was to
dimension the array as String. Arrays dimmed as Longs,Doubles,Variants all
transferred to the worksheet as values. Is that where the problem lies ?


Regards,
Vic Eldridge


"Bing" wrote:

Hi Vic,

Thanks i tried it.. i got an almost 6x speed improvement. Only 1 thing..
this operation seems to automatically convert numbers as text. So rather
than have to call aRange.PasteSpecial to convert from text back to numbers,
is there a way to do this so that the resize operation treats the data as is,
without converting to text.

Thanks again.

"Vic Eldridge" wrote:

Hi Bing,

Firstly, try replacing the following code ,

for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i

with this...

aRange.Resize(, UBound(newColumnArray) + 1) = newColumnArray


What this does is transfer the whole array to the worksheet in one fell
swoop, as opposed to transferring each element one by one. The speed gain
comes from the fact that your calls to Excel's slow Range object are reduced
from multiple calls, to a single call.
Now take this concept a little further. Instead of creating a 1-dimensional
array of each and every row, then transferring each row separately, you
should create a 2-dimensional array of all rows and columns, and transfer the
whole
array in one hit after EOF has been reached.

You'll be removing hundreds of thousands of calls to the Range object.
You're in for a nice surprise. It's gonna fly !


Regards,
Vic Eldridge



"Bing" wrote:

Hi,

I written a macro to read in line by line multiple CSV files of varying
lengths.

Can anyone suggest a faster way in terms of runtime execution time to speed
this code up?

ie. I thought of reading in multiple lines in bulk to reduce I/O but VBA
doesn't seem to have a bulk read mode.

Basically i do the following:

Dim columnArrays as Variant
Dim newColumnArray as Variant
.
.
Do until EOF(inputFile)
Line Input #inputFile, inputLine
columnArray = Split(inputLine, ",")
....merge/massage/apply functions to certain columns in columnArray
and copy into newColumnArray
for i = 0 to Ubound(newColumnArray)
aRange.Offset(0,i).Value = newColumnArray(i)
next i
set aRnage = aRange.Offset(1,0)
Loop

Thanks to everyone for their valuable insights.

Reply
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules

Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Populate Adjacent Cells based on Pull Down Selection edvwvw via OfficeKB.com New Users to Excel 0 June 30th 09 01:28 PM
Populate Adjacent Cells based on Pull Down Selection Ambassador New Users to Excel 0 June 29th 09 12:19 AM
transpose array of non-adjacent cells ignite ice Excel Worksheet Functions 3 June 18th 09 09:58 AM
Any quicker ideas? big t Excel Programming 8 October 6th 04 07:00 AM
Need to randomly populate a 10x10 array of cells with 100 names - 5 people listed 20 times each... Kevin Lyons[_2_] Excel Programming 3 February 8th 04 08:28 PM


All times are GMT +1. The time now is 12:41 PM.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Copyright ©2004-2025 ExcelBanter.
The comments are property of their posters.
 

About Us

"It's about Microsoft Excel"