Datatables - How to peek at next few rows? - asp.net

I have a datatable that I'm looping thru...
For Each drIndicator As DataRow In dtIndicatorsToProcess.Rows
Is there a way to "peek" at the next few rows to determine some things then continue?
Thanks!

You should use the for loop, something as shown below should suitable
For i = 0 To dtIndicatorsToProcess.Rows.Count - 1
Dim drIndicator As DataRow = dtIndicatorsToProcess.Rows(i)
'// Check ahead 2 rows
Dim drRowToCheck As DataRow = dtIndicatorsToProcess(i + 2)
'// Process here
Next

Related

User Form multi-selection Listbox arrays or entirerow.copy?

Amateur her so bear with me. I am trying to compile VBA code which runs a userform with list box populated with a 9 column and 100 row table from worksheet1. The user selects the only the items in the list box he needs for a report and they are to copied to worksheet 2.
With help from a 6 year old post on this site, I have managed to do this using an array and a public function to select the chosen rows and then output them to worksheets2. As follows:
Private Sub CommandButton1_Click()
Dim SelectedItems() As Variant
Dim i As Integer
Dim emptyrow As Integer
wsTarget.Activate
Range("A1").Select
SelectedItems = GetSelectedRisks(RiskList)
emptyrow = 15
For i = LBound(SelectedItems) To UBound(SelectedItems)
wsTarget.Cells(emptyrow, 2).Value = SelectedItems(i)
emptyrow = emptyrow + 1
Next
End Sub
Public Function GetSelectedRisks(lBox As MSForms.ListBox) As Variant
Dim tmpArray() As Variant
Dim i As Integer
Dim SelectionCounter As Integer
SelectionCounter = -1
For i = 0 To lBox.ListCount - 1
If lBox.Selected(i) = True Then
SelectionCounter = SelectionCounter + 1
ReDim Preserve tmpArray(SelectionCounter)
tmpArray(SelectionCounter) = lBox.List(i)
End If
Next
However I can only work out how to do this for the 1st column. I just can't work out how to get the other columns into the array and then back out again.
Should I be using an array or am I making this to complicated i.e. should I just be using loops and if selected, entirerow.copy type stuff?

Splitting a dataframe into parts by detection, then writing to multiple csv's?

I have a csv as shown in the image below. The data is a set of separate tables, separated by a blank line, that I require to be in separate csv files.
After importing to R, I'd like to split the data into the various separate tables, and then write these tables to separate csv files. I had the idea of using some kind of string detect, as a 'new' table is signified by the first instance of 'Area' in the first column. Any ideas of how to approach the code for this in R? There are a bunch of tables and doing this manually isn't advisable.
There's a truncation problem too it seems, as the tables will be required to have a differing amounts of columns, however I don't expect that getting rid of NULL or NA data should be too difficult with this.
Thanks for any help.
I don't think R is the right tool for this kind of thing. You should always try to use the right tool based on the task. Since you have Excel installed run this VBA script. That will do what you want.
Sub page_endings()
Dim i As Long 'how many times for pagebreak
Dim searchvalue_for_break_after 'value to do pagebreak
searchvalue_for_break_after = ""
'column A must be filled in with value break after
'example row 6, 12, 18, 24 whatever row you want
'will loop until empty row in column A
For i = 1 To Range("A" & Rows.Count).End(xlUp).Row + 1
If Range("A" & i).Value = searchvalue_for_break_after Then
'will add a pagebreak after the row with value break after
ActiveWindow.SelectedSheets.HPageBreaks.Add before:=Range("A" & i).Offset(1)
End If
Next i
Call Create_Separate_Sheet_For_Each_HPageBreak
End Sub
Sub Create_Separate_Sheet_For_Each_HPageBreak()
Dim HPB As HPageBreak
Dim RW As Long
Dim PageNum As Long
Dim Asheet As Worksheet
Dim Nsheet As Worksheet
Dim Acell As Range
'Sheet with the data, you can also use Sheets("Sheet1")
Set Asheet = ActiveSheet
If Asheet.HPageBreaks.Count = 0 Then
MsgBox "There are no HPageBreaks"
Exit Sub
End If
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'When the macro is ready we return to this cell on the ActiveSheet
Set Acell = Range("A1")
'Because of this bug we select a cell below your data
'http://support.microsoft.com/default.aspx?scid=kb;en-us;210663
Application.Goto Asheet.Range("A" & Rows.Count), True
RW = 1
PageNum = 1
For Each HPB In Asheet.HPageBreaks
'Add a sheet for the page
With Asheet.Parent
Set Nsheet = Worksheets.Add(after:=.Sheets(.Sheets.Count))
End With
'Give the sheet a name
On Error Resume Next
Nsheet.Name = "Page " & PageNum
If Err.Number > 0 Then
MsgBox "Change the name of : " & Nsheet.Name & " manually"
Err.Clear
End If
On Error GoTo 0
'Copy the cells from the page into the new sheet
With Asheet
.Range(.Cells(RW, "A"), .Cells(HPB.Location.Row - 1, "K")).Copy _
Nsheet.Cells(1)
End With
' If you want to make values of your formulas use this line also
' Nsheet.UsedRange.Value = Nsheet.UsedRange.Value
RW = HPB.Location.Row
PageNum = PageNum + 1
Next HPB
Asheet.DisplayPageBreaks = False
Application.Goto Acell, True
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
Call SaveWorksheetsAsCsv
End Sub
Sub SaveWorksheetsAsCsv()
Dim WS As Excel.Worksheet
Dim SaveToDirectory As String
Dim CurrentWorkbook As String
Dim CurrentFormat As Long
CurrentWorkbook = ThisWorkbook.FullName
CurrentFormat = ThisWorkbook.FileFormat
' Store current details for the workbook
SaveToDirectory = "C:\Users\Excel\Desktop\"
For Each WS In ThisWorkbook.Worksheets
Sheets(WS.Name).Copy
ActiveWorkbook.SaveAs Filename:=SaveToDirectory & ThisWorkbook.Name & "-" & WS.Name & ".csv", FileFormat:=xlCSV
ActiveWorkbook.Close savechanges:=False
ThisWorkbook.Activate
Next
Application.DisplayAlerts = False
ThisWorkbook.SaveAs Filename:=CurrentWorkbook, FileFormat:=CurrentFormat
Application.DisplayAlerts = True
' Temporarily turn alerts off to prevent the user being prompted
' about overwriting the original file.
End Sub
You should take each different table to the uppermost part. All in all, you have 5 tables with different dimensions (Table1: 11x13; Table2: 11x9; Table3: 3x12; Table4: 10x5; Table5: 6x7). Take them side-by-side in the above (A1:M11; N1:V11 etc.). The headings of tables would be in 1st row.
library(readxl)
# Use the path returned from getwd() function that is R's working directory
df <- as.data.frame(read_excel("C://Users//User//Documents//Revolution//Your.xlsx"))
Then, you can handle these 5 tables as:
Table1 <- df[,1:13]
Table2 <- df[,14:22]
Table3 <- df[1:3,23:34]
Table4 <- df[1:10,35:39]
Table5 <- df[1:6,40:46]
By caring dimensions stemmed from different row numbers in the assignmets, you do not face any NA or NULL value in Table1...Table5.

Add rows to datatable if distinct

I have a datatable which I keep cleaning and I put in values into it. So once in the execution time the data in the table looks like this
1211 A B C
1212 D E F
I have a datatable dt_new and add both these rows.(because first column is distinct).
Some times the data ends up like this
1213 I J K
1213 L M N
In this case I want to NOT add any of the row to my dt_new.(because first column is same for both rows)
How do i do this? Looks simple but i am ending up with varied results. I am checking by iterating the table and checking for first column but not getting result.
If you need more info, please ask.Thanks
For Each drTempRow As DataRow In dtTemp.Rows
Dim intCounter As Integer = 0
Dim intCounterEqual As Integer = 0
For Each drInnerRow As DataRow In dtTemp.Rows
If drTempRow("CustomerID") <> drInnerRow("CustomerID") Then
intCounter += 1
Else
intCounterEqual += 1
End If
Next
If intCounterEqual = 1 AndAlso intCounter <> dtTemp.Rows.Count - 1 Then
Dim drNewRow As DataRow = dt_new.NewRow()
drNewRow.ItemArray = drTempRow.ItemArray
dt_new.Rows.Add(drNewRow)
End If
Next
You can achieve it this way without a nested loop:
Remember: You must sort your dtTemp by CustomerID first, before use this code.
Dim dt_new As DataTable = dtTemp.Clone()
Dim previousId As String = ""
For Each drTempRow As DataRow In dtTemp.Rows
If Not drTempRow("CustomerID").ToString().Equals(previousId) Then
dt_new.ImportRow(drTempRow)
End If
previousId = drTempRow("CustomerID").ToString()
Next

Dynamically count of similar kind of Data

I have one data table in VB page which contain bulk data.In that data table one column named as vType and values in that column is one of Pr defined values such as 'A','B','C','D' etc , which comes from one Datable.
Now I want count of each type at the end.
For ex : CountA = 20,CountB=25 and so on .
Till now I have compared Each value using If condition which is static
For each dr as dataRow in dsType.rows
If dr("vType") = 'A' Then
CountA += 1
ElseIf dr("vType") = 'B' Then
CountB +=1
Next dr
and this If condition will repeat depend upon no of types in that data table (at max 8 fix values) I want to do this in single if condition ( Dynamic if Possible) Can I Count these values and store the same into single varaible? appreciate for you prompt reply.
You can use Linq-To-DataSet and Enumerable.GroupBy + Enumerable.Count on each group:
Dim typeGroups = dsType.AsEnumerable().
GroupBy(Function(row) row.Field(Of String)("vType")).
Select(Function(g) New With{ .Type = g.Key, .Count = g.Count(), .TypeGroup = g })
Note that New With creates an anonymous type in VB.NET with custom properties. So like a class on-the-fly which you can use in the current method.
Now you can enumerate the query with For Each:
For Each typeGroup In typeGroups
Console.WriteLine("Type:{0} Count:{1}", typeGroup.Type, typeGroup.Count)
Next
I cannot use Linq, i need to use simple vb only
Then use a Dictionary:
Dim typeCounts = New Dictionary(Of String, Integer)
For Each row As DataRow In dsType.Rows
Dim type = row.Field(Of String)("vType")
If (typeCounts.ContainsKey(type)) Then
typeCounts(type) += 1
Else
typeCounts.Add(type, 1)
End If
Next
Now you have a dictionary where the key is the type and the value is the count of the rows with this type.
why not getting the pretend result from the db itself?
Like so:
select count(*), vType
from someTable
group by vType
Not so sure about your question .. but this is what I've considered ..
You can make it as Sub ..
Sub AssignIncr(ByVal ds as DataSet,byval sFi as String,byval sCrit as String,ByRef Counter as Integer)
For each dr as dataRow in ds.rows
If dr(sFi) = sCrit Then Counter += 1
Next dr
End Sub
So you may use it by ..
AssignIncr(dsType,"vType","A",CountA)

Further problems with counting occurrences of strings in an Array

I am copying a question and answer from elsewhere as it partly goes into what I need but not completely.
In ASP classic, is there a way to count the number of times a string appears in an array of strings and output them based on string and occurrence count?
For example if I have an array which contains the following :
hello
happy
hello
hello
testing
hello
test
happy
The output would be:
hello 4
happy 2
test 1
testing 1
The answer that was given was this:
I'm assuming the language is VBScript (since that's what most people use with classic ASP).
You can use a Dictionary object to keep track of the individual counts:
Function CountValues(pArray)
Dim i, item
Dim dictCounts
Set dictCounts = Server.CreateObject("Scripting.Dictionary")
For i = LBound(pArray) To UBound(pArray)
item = pArray(i)
If Not dictCounts.Exists(item) Then
dictCounts.Add item, 0
End If
dictCounts.Item(item) = dictCounts.Item(item) + 1
Next
Set CountValues = dictCounts
End Function
This is great but I can't work out how to grab the top 2 most used words, display them and be able to put them in their own variable for use elsewhere.
Can anyone help with this?
You can loop through the dictionary object using this method. Inside that loop keep track of the top two keys and their counts in either a new array or two new variables.
You can't sort a Dictionary object in VBScript, so you have to use something else.
My advice is using a disconnected Recordset object to hold the items and their occurrences. Such object natively support sorting and it's pretty easy to use. To achieve this have such function instead:
Function CountValues_Recordset(pArray)
Dim i, item
Dim oRS
Const adVarChar = 200
Const adInteger = 3
Set oRS = CreateObject("ADODB.Recordset")
oRS.Fields.Append "Item", adVarChar, 255
oRS.Fields.Append "Occurrences", adInteger, 255
oRS.Open
For i = LBound(pArray) To UBound(pArray)
item = pArray(i)
oRS.Filter = "Item='" & Replace(item, "'", "''") & "'"
If (oRS.EOF) Then
oRS.AddNew
oRS.Fields("Item").Value = item
oRS.Fields("Occurrences").Value = 1
Else
oRS.Fields("Occurrences").Value = oRS.Fields("Occurrences").Value + 1
End If
oRS.Update
oRS.Filter = ""
Next
oRS.Sort = "Occurrences DESC"
oRS.MoveFirst
Set CountValues_Recordset = oRS
End Function
And using it to achieve the output you want:
Dim myArray, oRS
myArray = Array("happy", "hello", "hello", "testing", "hello", "test", "hello", "happy")
Set oRS = CountValues_Recordset(myArray)
Do Until oRS.EOF
Response.Write(oRS("item") & " " & oRS("Occurrences") & "<br />")
oRS.MoveNext
Loop
oRS.Close
Set oRS = Nothing
Don't forget to close and dispose the recordset after using it.

Resources