Creating array of cells in itextsharp for VB.NET - arrays

I am trying to create a pdf with a table with each cell having lots of different properties (i.e. border widths and text font, etc.) so instead of having to write out the code 500 times fore each individual cell I want to have an array of cells. I have the following code:
Imports iTextSharp.text.pdf
Imports iTextSharp.text
Imports System.IO
Public Class pdfQuote
Dim cell() As PdfPCell
Dim table As New PdfPTable(7)
Dim n As Integer = 0
Public Sub createNewQuote()
newCell("test")
End Sub
Public Sub newCell(text As String)
n += 1
cell(n) = New PdfPCell(New Phrase(text))
table.AddCell(cell(n))
End Sub
End Class
I get the error: "Object reference not set to an instance of an object"
Any help would be much appreciated.
Thanks in advance

If you really want to make your life easier switch from an array to List. By doing that you don't need to keep track of the current index.
Public Class pdfQuote
Dim cells As New List(Of PdfPCell)
Dim table As New PdfPTable(7)
Public Sub createNewQuote()
newCell("test")
End Sub
Public Sub newCell(text As String)
cells.Add(New PdfPCell(New Phrase(text)))
table.AddCell(cells.Last)
End Sub
End Class
EDIT
Also I'd recommending creating some helper methods so that you can share as much code as possible. This post has a simple example of that.

Related

Error reading JArray from JsonReader VB.net

where does it go wrong?
my coding
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Imports System.Net
Public Class DigiposAJA
Private Sub CekPaket()
Dim json As String = (New WebClient).DownloadString("http://192.168.101.1:100/list_product?username=SIP12&category=ROAMING&to=0811&payment_method=LINKAJA&json=1")
Dim jarr As JArray = Linq.JArray.Parse(json)
Dim sKatagori As String
For Each jtk As JToken In jarr
sKatagori = jtk.SelectToken("kategori")
DgvDigipos.Rows.Add()
DgvDigipos.Rows(DgvDigipos.Rows.Count - 1).Cells("DgvKategori").Value = sKatagori
Next
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
CekPaket()
End Sub
End Class
after I debug the result is an error like this.
Newtonsoft.Json.JsonReaderException: 'Error reading JArray from JsonReader. Current JsonReader item is not an array: StartObject. Path '', line 1, position 1.'
Can you help me to get a great result
Most likely this is a result of your call to the web service not returning the result you expect.
This is actually a good example of the benefits of separation of concerns and strongly typed objects. Your sub CekPaket should be broken down into 3 parts. 1) get the string. This should be a function and should use some sort of configuration to get the end point and have appropriate guards for failure, 2) parse the string into a strongly typed object (IEnumerable of whatever), this should validation to make sure that the input is good. You might want to make this function public for easy testing. And finally 3) bind your results to your UI. It looks like you are doing this part by hand, whenever possible you should allow the frame work to do this for you by providing a data source and a template for the display.

Winforms Data from database across multiple forms

I have a winforms applications that has an ms sql server backend. In my database i have lookup tables for like status, and other tables where the data rarely changes. In my application, several forms might use the same lookup tables (Some have a lot of data in them). Instead of loading/filling the data each time the form is open, is there a way to cache the data from the database that can be accessed from multiple forms. I did some searching, but couldnt find the best solution. There is caching, dictionaries, etc. What is the best solution and can you point me to the documentation that discusses it and may even have an example.
Edit:
In my original post I failed to mention that I have a strongly typed dataset and use tableadapters. I want to preload my lookup tables when my application starts, and then have these dataset tables be used throughout the application, on multiple forms without having to fill them on every form.
I have tried creating a class:
Public Class dsglobal
Public Shared EML_StaffingDataSet As EML_StaffingDataSet
Public Shared Sub populateDS()
EML_StaffingDataSet = New EML_StaffingDataSet
End Sub
Public Shared Sub loadskills()
Dim ta As New EML_StaffingDataSetTableAdapters.TSTAFFSKILLTableAdapter
ta.Fill(EML_StaffingDataSet.TSTAFFSKILL)
End Sub
End Class
I run this on a background worker when my application is starting up. So it loads the dataset table. On fill, I can see the datatable has data in it. When I open a form, i want to use the dataset table, but it seems to clear the data out. Not sure if my approach is correct or where my error is.
Edit2:
I have also tried this per comments, but not sure I am doing it correctly. If I am doing it correctly, then how do I use that as a datasource at design time, can i only do that programmatically?
Public Module lookupdata
Private EML_StaffingDataSet As EML_StaffingDataSet
Private skillvalues As List(Of skill)
Public ReadOnly Property skill As List(Of skill)
Get
If skillvalues Is Nothing Then
getskillvalues()
End If
Return skillvalues
End Get
End Property
Private Sub getskillvalues()
skillvalues = New List(Of skill)
EML_StaffingDataSet = New EML_StaffingDataSet
Dim ta As New EML_StaffingDataSetTableAdapters.TSTAFFSKILLTableAdapter
ta.Fill(EML_StaffingDataSet.TSTAFFSKILL)
For Each row As DataRow In EML_StaffingDataSet.TSTAFFSKILL
Dim skill As New skill
skill.skill_id = row("skill_id")
skill.skill_desc = row("skill_desc")
skill.skill_open_ind = row("skill_open_ind")
skillvalues.Add(skill)
Next
End Sub
End Module
Public Class skill
Public Property skill_id As Integer
Public Property skill_desc As String
Public Property skill_open_ind As Boolean
End Class
You might want to consider a lazy loading pattern, like this:
Public Module LookupData
Private statusValues As List(Of LookupValue)
Public Readonly Property Statuses As List(Of LookupValue)
Get
If statusValues Is Nothing Then
GetStatusValues()
End If
Return statusValues
End Get
End Property
Private Sub GetStatusValues()
statusValues = New List(Of LookupValue)
Dim sql = "select key, value from StatusTable"
'TODO: Read the items from the database here, adding them to the list.
End Sub
End Module
Public Class LookupValue
Public Property Key As String
Public Property Value As String
End Class
The idea is that you've got a single instance of LookupData (a Module in VB, there can be only one). Lookup data has a series of Properties, each of which returns a list of values from the database. If the data has already been loaded, it just returns what it has cached. If the data has not been loaded, then the first time it is referenced it retrieves it from the database.
You can consume it elsewhere in your code as follows:
Dim myStatuses = LookupData.Statuses

Exception with sqlite database "no such table"

First of all I´m developing a database with autosuggest box. I´ve created a database with DB Browser and imported data. I was reading documentation in C# how connect database and retrieve data. The issue is show up an exception error:
enter image description here
I´ve connected the database in properties with content option. I paste the code:
Public NotInheritable Class METARTAF
Inherits Page
Dim dbpath As String = Path.Combine(ApplicationData.Current.LocalFolder.Path, "airportsdb.sqlite3")
Dim conn As SQLite.Net.SQLiteConnection = New SQLite.Net.SQLiteConnection(New WinRT.SQLitePlatformWinRT(), dbpath)
Dim airportinfo As List(Of String) = Nothing
Public Sub New()
' This call is required by the designer.
InitializeComponent()
End Sub
Private Sub AutoSuggestBox_TextChanged(sender As AutoSuggestBox, args As AutoSuggestBoxTextChangedEventArgs)
Dim datairport As New List(Of String)
Dim retrieve = conn.Table(Of flugzeuginfo)().ToList
If args.Reason = AutoSuggestionBoxTextChangeReason.UserInput Then
If sender.Text.Length > 1 Then
For Each item In retrieve
datairport.Add(item.IATA)
datairport.Add(item.ICAO)
datairport.Add(item.Location)
datairport.Add(item.Airport)
datairport.Add(item.Country)
Next
airportinfo = datairport.Where(Function(x) x.StartsWith(sender.Text)).ToList()
sender.ItemsSource = airportinfo
End If
Else
sender.ItemsSource = "No results..."
End If
End Sub
Private Sub AutoSuggestBox_SuggestionChosen(sender As AutoSuggestBox, args As AutoSuggestBoxSuggestionChosenEventArgs)
Dim selectedItem = args.SelectedItem.ToString()
sender.Text = selectedItem
End Sub
Private Sub AutoSuggestBox_QuerySubmitted(sender As AutoSuggestBox, args As AutoSuggestBoxQuerySubmittedEventArgs)
If args.ChosenSuggestion Is Nothing Then
stationidtxt.Text = args.ChosenSuggestion.ToString
End If
End Sub
Anyone could help about this?
Before you query or insert into a table, you should CREATE it. This tells SQLite what columns you have and suggests datatypes (on other rdbms's you get actual data type enforcement but SQLite does not do that). If this is your problem, you will want to spend some time with the SQLite documentation on data types and the ability to hook them into your application.
On the other hand, as you seem to be trying to retrieve data, this suggess one of two things is wrong. Either you care connecting to the wrong db (in which case SQLite will usually helpfully create an empty db for you!) or else you are specifying the wrong table.

How do I add a string to an array in visual basic net

I have been looking for the specified code all day long, browsing through the MSDN libraries from microsoft, but I wasn't able to find or come up with a solution:
Question: How can I add a string to an existing array?
I have been trying this
Dim Items() As String
Items = ListBox1.Items.Cast(Of String).ToArray
Array.Reverse(Items)
Me.ListBox1.Items.Clear()
Me.ListBox1.DataSource = Items
**Items.add("Add This to my array")**
But this doesn't work unfortunately.
My code is loading a populated listbox into an array (reverses the entries, and then cleans the listbox before populating it with the array).
How can I add to this array now?
Try this.....
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim Items As List(Of String)
Items = ListBox1.Items.Cast(Of String).ToList
Items.Reverse()
Items.Add("Add This to my array")
Me.ListBox1.Items.Clear()
Me.ListBox1.DataSource = Items
End Sub
End Class
almost identical code (slightly rearranged), using a List instead of an array

Type mismatch on an Array assignment in ASP

Its been a while since I've worked with ASP, but I'm getting a Type mismatch error on what seems to be a simple assignment statement. Can anyone shed some light on why this might be happening.
This works, but when I try to foreach an unassigned Questions block I get an Object not a collection error
Class Survey
public ID
public Title
public Questions
End Class
Sub Test()
Dim oSurvey
Set oSurvey = new Survey
Dim aQuestions(2)
Set aQuestions(0) = new Question
' Other aQuestions assignments
oSurvey.Questions = aQuestions
End Sub
Alternately If I setup questions as a dynamic array then the assignment fails with a type mismatch error.
Class Survey
public ID
public Title
public Questions()
End Class
Sub Test()
Dim oSurvey
Set oSurvey = new Survey
Dim aQuestions(2)
Set aQuestions(0) = new Question
' Other aQuestions assignments
' Throws a Type mismatch error here
oSurvey.Questions = aQuestions
End Sub
Any thoughts?
To answer your question as to what is actually going on.
when I try to foreach an unassigned
Questions block I get an Object not a
collection error
For Each enumerates a set of variants from the source variable, it does this by acquiring an IEnumVARIANT. If the source variable holds an object it is expected to have an implementation of this interface. If it is an array VBScript creates an implementation dynamically and it can only do this if the array has been dimensioned. Anything else in the source variable (such as Empty in this case) will result in an error.
then the assignment fails with a type mismatch error.
The left hand side of an assignment operation must always be a variant. Hence its not possible copy the contents of one dynamic array to another via a simple assignment.
Your first approach is reasonably sound but you need a way to represent an empty array without crashing out a For Each. You can use this little trick:-
Function EmptyArray
EmptyArray = Split("", " ")
End Function
Class Survey
public ID
public Title
public Questions
Private Sub Class_Initialize
Questions = EmptyArray
End Sub
End Class
Now if you try to For Each the Questions before it has been assigned a real array the for each will do nothing as expected. Also if you use UBound(Questions) + 1 to get the count of questions that will still be accurate since UBound(EmptyArray) is -1.
If I try to paste the same code into VBA (excel or word), it doesn't compile.
It shows error on line public Questions() saying
---------------------------
Microsoft Visual Basic
---------------------------
Compile error:
Constants, fixed-length strings, arrays, user-defined types and Declare statements not allowed as Public members of object modules
---------------------------
OK Help
---------------------------
In the first example, you haven't defined it as an array (it is a variant & hence can be assigned any value).
Update: I tested this in ASP.NET not realizing the question was about classic ASP. I've modified the code below to work with classic ASP, though I haven't been able to test it yet:
Class Question
...
End Class
Class Survey
Public ID
Public Title
Public Questions As Question()
End Class
Sub Test()
Dim oSurvey As New Survey
Dim aQuestions(0 To 2) As Question
Set aQuestions(0) = New Question
...
Set oSurvey.Questions = aQuestions
End Sub
In your first example, Survey.Questions isn't a collection; in your second, it is an array of Type Variant.
So I ended up sticking with the Array declaration. Additionally, When I tried to ReDim the array like so I got an error.
ReDim oSurvey.Questions(2)
So I created a sub routine to ReDim the Array, and this worked.
Class Survey
public ID
public Title
public Questions()
sub ReDimQuestions(count)
ReDim Questions(count)
end sub
End Class
Sub Test()
Dim oSurvey
Set oSurvey = new Survey
oSurvey.ReDimQuestions 2
Set oSurvey.Questions(0) = new Question
' Other aQuestions assignments
End Sub

Resources