I have some code that works for smaller data sets. I get an 'out of memory' error with the huge data sets I use though (800k rows, 25 columns). I was trying to figure out a way to change this to mass export column by column, or maybe split up sets of rows, instead of the whole thing at once.
Clearly it can't handle that much data. I couldn't figure out how to separate it out some. Any ideas? Thanks!
For Each dt As System.Data.DataTable In ds.Tables
' Copy the DataTable to an object array
Dim rawData(dt.Rows.Count, dt.Columns.Count - 1) As Object
' Copy the column names to the first row of the object array
For col = 0 To dt.Columns.Count - 1
rawData(0, col) = dt.Columns(col).ColumnName
Next
' Copy the values to the object array
For col = 0 To dt.Columns.Count - 1
For row = 0 To dt.Rows.Count - 1
rawData(row + 1, col) = dt.Rows(row).ItemArray(col)
Next
Next
' Calculate the final column letter
Dim finalColLetter As String = String.Empty
Dim colCharset As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Dim colCharsetLen As Integer = colCharset.Length
If dt.Columns.Count > colCharsetLen Then
finalColLetter = colCharset.Substring( _
(dt.Columns.Count - 1) \ colCharsetLen - 1, 1)
End If
finalColLetter += colCharset.Substring( _
(dt.Columns.Count - 1) Mod colCharsetLen, 1)
' Fast data export to Excel
Dim excelRange As String = String.Format("A1:{0}{1}", finalColLetter, dt.Rows.Count + 1)
excelSheet.Range(excelRange, Type.Missing).Value2 = rawData
excelSheet = Nothing
Next
Is there other code that manipulates the excel spreadsheet? If not, it would probably be faster to just write this out to a plane text file in CSV format. Excel will open the CSV and present it like a normal spreadsheet.
Related
I am updating some old software in VB, and fixed this, but I'd like to know how to make the second option work.
The problem is in the second For loop in the code below. I'm not sure how to get a column of a specific row.
I have not worked much with VB and not used it for 10 years or so, so bare the question.
Dim i As Integer = 0
Dim dsSettings As New DataSet
dsSettings.Locale = System.Globalization.CultureInfo.InvariantCulture
If System.IO.File.Exists("QuaData\Settings.xml") Then
dsSettings.ReadXml("QuaData\Settings.xml")
ReDim Preserve IdPrefixes(dsSettings.Tables(0).Rows.Count - 1)
For Each Row As DataRow In dsSettings.Tables(0).Rows
For Each Coll As DataColumn In dsSettings.Tables(0).Columns
IdPrefixes(i) = Row("IdPrefix").ToString()
Next
i = i + 1
Next
' Here I cannot see how I can get a column of a row -
' like Rows(1)
' I cannot select Rows(index)(column name)
For i = 0 To dsSettings.Tables(0).Rows.Count - 1
IdPrefixes(i) = dsSettings.Tables(0).Rows(i)("IdPrefix").ToString()
Next
End If
I am a newbie then a self taught only,
I have a datagridview that will load the data from my database and it has a hidden column I want to export a selected row of data into excel but what I want to export is the only visible column in my datagridview to excel and the selected row only
I don't know how to do this right!
How can I combine this? the selected column and only visible column will be exported in my excel
For i = 0 To SelectedRowCount - 1
currentVisibleColumn = columnCollection.GetFirstColumn(DataGridViewElementStates.Visible)
lastColumnExported = currentVisibleColumn
For j = 1 To visibleColumnCount + 1
Dim value = DataGridView1.Rows(i).Cells(currentVisibleColumn.Index).Value
If value IsNot vbNullString Then
xlWorkSheet.Cells(i + 2, j) = value.ToString()
xlWorkSheet.Cells(i + 2, j + 1) = DataGridView1(j, DataGridView1.SelectedRows(i).Index).Value.ToString()
End If
currentVisibleColumn = columnCollection.GetNextColumn(lastColumnExported, DataGridViewElementStates.Visible, DataGridViewElementStates.None)
lastColumnExported = currentVisibleColumn
Next
Next
when I do this it gives me "'Object reference not set to an instance of an object.'"
Your code should be more like this:
Dim columns = (From column In DataGridView1.Columns.Cast(Of DataGridViewColumn)()
Where column.Visible
Order By column.DisplayIndex).ToArray()
For Each row As DataGridViewRow In DataGridView1.SelectedRows
For Each column In columns
Dim value = row.Cells(column.Index)
If value IsNot Nothing Then
'...
End If
Next
Next
If you still get a NullReferenceExceptionwith that code then you'll need to be more specific about it to get more help but the solution to such issues is almost always the same.
I have to make a application to load images in excel vba, encrypt that image and save it in cells. My problem is the limit of characters in cell ( 32.767 characters ) and my encrypted string is like 800k characters.
I make a function to make a array of string with custom string character length to save in a row but when i save in cells i recive this error:
Public Function SplitString(ByVal TheString As String, ByVal StringLen As Integer) As String()
Dim ArrCount As Integer 'as it is declared locally, it will automatically reset to 0 when this is called again
Dim I As Long 'we are going to use it.. so declare it (with local scope to avoid breaking other code)
Dim TempArray() As String
ReDim TempArray((Len(TheString) - 1) \ StringLen)
For I = 1 To Len(TheString) Step StringLen
TempArray(ArrCount) = Mid$(TheString, I, StringLen)
ArrCount = ArrCount + 1
Next
SplitString = TempArray 'actually return the value
End Function
Dim StringArray As Variant
StringArray = SplitString(EncodeFile(.SelectedItems(1)), 30000)
Dim ind As Integer
ind = 2
For index = 1 To UBound(StringArray)
Sheet5.Cells(55, ind).value = StringArray(index)
ind = ind + 1
Next index
I solve this problem by adding a delay in for loop but it's not a optimal solution
For index = 1 To UBound(StringArray)
Sheet5.Cells(55, ind).value = StringArray(index)
ind = ind + 1
Application.Wait (Now + TimeValue("00:00:01"))
Next index
And now the question: Can I make this more faster or a better way to solve this problem ?
Dump the array into the cells within one row without the loop.
Sheet5.Cells(55, "A").resize(1, ubound(StringArray) + 1) = StringArray
I have a simple task that i need to automate.
I get a email in a very specific format from another application based on a trigger.
What i want is that out look "reads" the data in that email and compare two cells. if one cell is greater than the other, then i want the email forwarded to a specified address otherwise delete the email.
the folowing vba code was attempted, but gives a run time error. please guide
Sub GetLines()
Dim msg As Outlook.mailItem
Dim rows As Variant
Dim numberofColumns As Long
Dim numberofRows As Long
Dim headerValues As Variant
Dim headerRow() As String
Dim data() As String
Dim i As Long, j As Long
' get currently selected email
Set msg = ActiveExplorer.Selection.item(1)
' tokenize each line of the email
rows = Split(msg.Body, vbCrLf)
' calculate array size
numberofColumns = Len(rows(0)) - Len(Replace(rows(0), Chr(9), ""))
numberofRows = UBound(rows) + 1
' put header row into array
ReDim headerRow(1 To numberofColumns)
headerValues = Split(rows(0), Chr(9))
For i = 1 To numberofColumns
headerRow(i) = Trim$(headerValues(i - 1))
Next i
' calculate data array size
numberofRows = numberofRows - 1
' put data into array
ReDim data(1 To numberofRows, 1 To numberofColumns)
For i = 1 To numberofRows
For j = 1 To numberofColumns
data(i, j) = Trim$(Split(rows(i), Chr(9))(j - 1))
Next j
Next i
End Sub
Your code makes too many unnecessary assumptions about the data and will give errors most of the time. Firstly you need to use F8 to step through the code to isolate the error in a particular line.
I suggest you change
Dim data() As String
to
Dim data As Variant
data = Array()
I'm not an expert in how VBA manages memory but I know that I get a lot less grief when I make things variants.
You are most likely to have a problem here:
For i = 1 To numberofRows
For j = 1 To numberofColumns
data(i, j) = Trim$(Split(rows(i), Chr(9))(j - 1))
Next j
Next i
What if not every row is perfectly formed?
Instead, try this:
For i = 1 To numberofRows
For j = 1 To Ubound(Split(rows(i), Chr(9))) + 1
data(i, j) = Trim$(Split(rows(i), Chr(9))(j - 1))
Next j
Next i
This allows your code to "survive" a blank line or some other error in the data.
I just want to mention first, I do appreciate everyone who gives of their knowledge to help others learn...
I have been able to piece together code that exports my Datgrid to an Excel file and works fine, except I am only getting the first row of the datagrid. since the datagrid could contain one record, or hundreds, I need all rows to export to Excel.
Here is what I have been able to put together (again, it works fine, file is saved with column headers, but only writes the first row of data from my datagrid):
'Export to Excel
Dim ExApp1 As Excel.Application
Dim ExWkbk1 As Excel.Workbook
Dim ExWksht1 As Excel.Worksheet
Dim MisValue As Object = System.Reflection.Missing.Value
Dim i As Integer
Dim j As Integer
ExApp1 = New Excel.Application
ExWkbk1 = ExApp1.Workbooks.Add(MisValue)
ExWksht1 = ExWkbk1.Sheets("sheet1")
For i = 0 To dg7.RowCount - 2
For j = 0 To dg7.ColumnCount - 1
ExWksht1.Cells(i + 2, j + 1) = dg7(j, i).Value.ToString()
For k As Integer = 1 To dg7.Columns.Count
ExWksht1.Cells(1, k) = dg7.Columns(k - 1).HeaderText
ExWksht1.Cells(i + 2, j + 1) = dg7(j, i).Value.ToString()
Next
Next
Next
ExWksht1.SaveAs("C:\MyExcel.xlsx")
ExWkbk1.Close()
ExApp1.Quit()
releaseObject(ExApp1)
releaseObject(ExWkbk1)
releaseObject(ExWksht1)
Again, many thsanks in advance for helping me learn
First of all it seems to me this is a DataGridView as opposed to a DataGrid since from what I know DataGrid does not have "RowCount" or "ColumnCount" properties in either WinForms or Web.UI (I could be wrong).
If it is so is there a specific reason for
dg7.RowCount - 2
If the object you are trying to get data from is indeed a DataGridView then I suppose this task is to omit new(empty) rows. If I am correct that you are trying to export data from a DataGridView this way there is a property for the DataGridViewRow that will serve this purpose:
IsNewRow
So (while I have not used Excel in VB.NET recently) your cycle could be:
For i = 0 To dg7.ColumnCount - 1
ExWksht1Cells(1 , i + 1) = dg7.Columns[i].HeaderText
Next
For i = 0 To dg7.RowCount - 1
If Not dg7.Rows(i).IsNewRow Then
For j = 0 To dg7.ColumnCount - 1
ExWksht1.Cells(i+ 2, j + 1) = dg7(i, j).Value.ToString()
Next
End If
Next
As far as the excel object calls I can't give a reasonable comment since I've not used that object too much.Let me know if that's useful and/or correct.