|
I don't see anything wrong with your answer. It's certainly better than any of the others!
Edit: Apart from the fact that you're relying on Option Strict Off ; you should probably add a DirectCast in the handlers.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I want to download data every five minutes from a Davis Weather Station. The code that actually talks to the hardware is in a DLL, and I don't have access to the source (or to terribly good documentation, sadly!). My code that does the downloading (below) works reliably and without problems if called in the normal way. If it is called from a System.Timer OnElapsed thread, the program (run in Debug mode) crashes immediately without reporting what is going wrong. The variables and structures starting with g are defined outside any Functions in a Module, so they have global scope, as do WSInitialized and USBSerialNumber. I think that everything else is fairly obvious. Commenting out the one line which retrieves text data into a StringBuilder seems to fix the problem, and I can do without that data, but I would like to know what is going on, since I may want to do something in the future where the use of StringBuilders to receive data (if that is what is causing the problem) is less optional.
Private Sub Get_Davis_WeatherData(ByRef gwdcurrent As WeatherData)
Dim dtsTemp As New DateTimeStamp
Dim sbWindDir As New StringBuilder(5)
If Not WSInitialized Then
CloseUSBPort_V()
USBSerialNumber = GetUSBDevSerialNumber_V()
If (OpenUSBPort_V(USBSerialNumber) = 0) Then
If (InitStation_V() = COM_ERROR) Then
MsgBox("Cannot initialize the USB port for the Weather Station")
Exit Sub
Else
SetCommTimeoutVal_V(100, 100)
WSInitialized = True
End If
Else
MsgBox("Cannot open the USB port for the Weather Station")
Exit Sub
End If
End If
If (GetStationTime_V(dtsTemp) = 0) Then gwdcurrent.Time = DateStamp2UnixTime(dtsTemp)
If LoadCurrentVantageData_V() = 0 Then
gwdcurrent.OutTempF = GetOutsideTemp_V()
gwdcurrent.OutHum = GetOutsideHumidity_V()
gwdcurrent.BPressure = GetBarometer_V()
gwdcurrent.WindChillF = GetWindChill_V()
gwdcurrent.DewPointF = GetDewPt_V()
gwdcurrent.RainTotal = GetTotalRain_V()
gwdcurrent.Rain24h = GetDailyRain_V()
gwdcurrent.Rain1h = GetRainRate_V()
gwdcurrent.WindSpeedMPH = GetWindSpeed_V()
gwdcurrent.WindRDir = GetWindDir_V()
gwdcurrent.WindDir = GetWindDirStr_V(sbWindDir).ToString
gsngRainMTD = GetMonthlyRain_V()
End If
If gsnsSensor.IsUpToDate Then
gwdcurrent.InHum = gsnsSensor.Humidity
gwdcurrent.InTempF = gsnsSensor.TempF
ElseIf tcHouse.Online Then
gwdcurrent.InTempF = tcHouse.CurrentTemp
gwdcurrent.InHum = tcHouse.CurrentHumidity
End If
End Sub
|
|
|
|
|
If you're using the System.Timers.Timer (there is no System.Timer!), the Elapsed callback is done on a background thread. If the library you're using is not written to handle that, it may screw up the library like you're seeing. You'll have to check with the people who wrote that library to find out.
If possible, you can swap out the System.Timers.Timer with the Timer object in the Toolbox. That's the Forms-based Timer and runs on windows messaging Events, but needs to be used in a Windows Forms app, not a Console app or WPF. These events are always raised on the UI (startup) thread and shouldn't give you the problem that you're seeing.
|
|
|
|
|
Yes, it is/was a System.Timers.Timer. I had a vague memory of this sort of problem responding to switching to a Forms timer, so I did try that (my app normally keeps a main Form instantiated, even though it was written as a Console App). This, however, also resulted in a crash when the timer fired and the code executed - I left the Form open for the test.
|
|
|
|
|
Dim sbWindDir As New StringBuilder(5)
gwdcurrent.WindDir = GetWindDirStr_V(sbWindDir).ToString
So you pass an empty StringBuilder instance with a capacity of 5 characters to the GetWindDirStr_V function. What does happen in that function? How does the signature of the function of the thirdparty dll look like, and how does your DllImport statement look like?
Other values called seem to be numeric types, and this one is a string type. Hence I guess the problem is actually in the marshalling of the non-managed "string" to the managed string. Also the length of the string could be wrong: what about "SouthEast" with 9 characters or "NorthNorthWest" with 14? I.e. a simple buffer overflow, actually independent from threading issues.
|
|
|
|
|
The documentation of the DLL is (to put it politely) somewhat sketchy - for this routine:
'char* GetWindDirStr_V (char* dirStr)
Description
This function gets the currenct (sic!) wind direction in string representation.
Return Values
current wind direction
"---" represents no data available.'
The DllImport statement is:
<DllImport("VantagePro.dll", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.StdCall)> _
Public Function GetWindDirStr_V(dirStr As StringBuilder) As StringBuilder
End Function
While string length overflow is an obvious possibility, the longest string actually passed is three characters (e.g. 'NNE'), and buffers for text wind direction strings which are explicitly sized elsewhere in Structures passed to and from the DLL are always char(5). In addition, the code was extensively exercised without any problems outside timer OnElapsed routines and worked fine - it only fails when called from interrupt code.
|
|
|
|
|
If you enclose the line gwdcurrent.WindDir = GetWindDirStr_V(sbWindDir).ToString in a try-catch block, can you catch an exception? If so, what's the message - and GetLastError's message?
|
|
|
|
|
I had not previously tried that, but I did, with Debug.Print commands inserted to display the information. Unfortunately, the crash is a Windows "This application has stopped working" one, which is apparently not prevented by exception-trapping the line of code that provokes it, and it won't let me 'Debug' it with the open instance of VS.
|
|
|
|
|
Hi all. First of all I know that there are a lot of questions like mine, but I just can't solve it.
Secondly, this app have to export XML format from spritesheet to a file.
What I did is just create a simple button, added Macro and pasted this code into:
Sub ExportXML()
Const ForReading = 1
Const ForWriting = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
newFileName = Application.GetSaveAsFilename("out.xml", "XML Files (*.xml), *.xmls")
If newFileName = False Then
Exit Sub
End If
If objFSO.FileExists(newFileName) Then
objFSO.DeleteFile (newFileName)
End If
ActiveWorkbook.XmlMaps("Root_Map").Export URL:=newFileName
Set objFile = objFSO.OpenTextFile(newFileName, ForReading)
Dim count
count = 0
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
If count = 0 Then
strNewContents = strNewContents & "<?xml version=""1.0"" ?>" & vbCrLf
ElseIf count = 1 Then
strNewContents = strNewContents & "<Root xmlns=""http://tempuri.org/import.xsd"">" & vbCrLf
Else
strNewContents = strNewContents & strLine & vbCrLf
End If
count = count + 1
Loop
objFile.Close
Set objFile = objFSO.OpenTextFile(newFileName, ForWriting)
objFile.Write strNewContents
objFile.Close
End Sub
When I have a basic table with data and a button, which when I press it, I get to the Save As screen. I save it as "out.xml" in my Desktop, but I when press OK, i got and error saying : " Run-time error '9': Subscript out of range ' ", and this
ActiveWorkbook.XmlMaps("Root_Map").Export URL:=newFileName line becomes yellow. What I am doing wrong in here? Thank you very much and appreciate any help from you guys .
|
|
|
|
|
Looking at the documentation[^], that error suggests that your active workbook doesn't contain an XML map with the name "Root_Map".
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
So I need to create a new XML document? But I want to actually export a spreadsheet file to an XML format file. Now I am confused.
|
|
|
|
|
Well, you need to Add an XmlMap[^] before you can access it.
If you just want to export the sheet to XML, there are several suggestions here[^].
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thank you very much, Richard.
|
|
|
|
|
General question. I am new to Visual Basic, but have done my share of programming; albeit years ago. I understand the logic of programming, but my question is more about "best practices"
Background:
I'd like to create a program that stores a person's information (Name, contact #, email etc). For each person I'd like to have an array of times for various bike races. Optimally I'd have the ability to store split times as well. Now, different people may have a different number of races.
My question: What is best practice for the type of variables to create for such a project. Array list? Structures? I'm sure there are many ways to index the data with the person, but I'd like to do it in the best, most efficient manner.
Thanks
|
|
|
|
|
Tables, relational.
One table with people, one with races, one that combines a race, a person, and a time. Easy to query.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
so, is this a hashtable? an array? what is used in VB to set up a table, relational?
|
|
|
|
|
DJHJr wrote: table, relational
Fairly certain his is talking about a relational database.
|
|
|
|
|
I guess my question is more rudimentary. Trying to get my brain around the "best practice" for an indexed array from a VB programming perspective. I have 12 people who could have anywhere from 1 to 20 races. Each race has 4 "split" times. I want to be able to analyze the racers and various stats based on times and courses run. I can handle the "programming logic" I'm struggling with the Programming part of the data organization.
|
|
|
|
|
Okay.... and nothing you have said changes that the "best practice" based on the information that you have provided to us at this time is to use a database. If for some reason that you cannot or will not use a database to store and manipulate your data, then I suppose that the next best thing for you to do would be to use a List.
|
|
|
|
|
thanks...I think I am being thick...I'll read up on database structures. Will keep you posted with my progress
|
|
|
|
|
Okay. I've done some more work, and created some tables and have my logic, Tables, and Keys planned. My consternation now is how to open connections to SQL databases. I cant seem to find a good resource on how to create and then read/write to the database. Any ideas??
|
|
|
|
|
I wrote a small utility app for printing invoices from a DOS Accounting system in PDF format.
I probably made the mistake of placing the Adobe PDF object in a dialog window that I created. I call the dialog window, run a Sub new and program the PDF object to load the PDF which works great except for the action below.
But it always tries to load the PDF in the Adobe Viewer first, and says "Cannot use Adobe Reader to view PDF in your web browser, Reader will now exit. Please exit your browser and try again." So I click OK or something and the Adobe Reader window closes and my dialog appears with the PDF loaded, all formatted and everything.
I'm just trying to get rid of the error message. Any insight or suggestions are appreciated.
|
|
|
|
|
Assignment
It’s often necessary to convert between units. In this exercise, you will create two functions for converting between units of distance. The first function will be called ConvertMilesToKilometers(), which will accept one parameter for the number of miles. It will return the equivalent number of kilometers. The second function will be called ConvertKilometersToMiles() and will accept kilometers as its parameter; this will return the equivalent number of miles.
The main method will ask the user if he or she wants to convert miles to kilometers or kilometers to miles. It will then ask for the number of miles or kilometers. It will call the appropriate method and display the converted value.
To convert miles to kilometers, divide miles by 0.62137. To convert kilometers to miles, multiply kilometers by 0.62137.
Example
Do you want to convert to Miles or Kilometers? (M or K): K
Enter number of Kilometers: 3.5
3.5 kilometers equals 2.174795 miles.
|
|
|
|
|
This is what I have so far, but I can't get past putting in the number of units to use. I feel like I'm never going to get a hang of this coding stuff.
Module Module1
Dim miles As Decimal = 0
Dim kilometers As Decimal = 0
Dim answer As String
Sub Main()
Console.WriteLine("Do you want to convert miles or kilometers?")
answer = Console.ReadLine()
If answer = "miles" Then
Console.WriteLine("What is the number of miles?")
Console.ReadLine()
Call convertMilesToKilometers()
Console.WriteLine("The converted value is: " & kilometers)
ElseIf answer = "kilometers" Then
Console.WriteLine("What is the number of kilometers?")
Console.ReadLine()
Call convertKilometersToMiles()
Console.WriteLine("The converted value is: " & miles)
End If
Console.ReadLine()
End Sub
Function convertMilesToKilometers() As Decimal
kilometers = miles / 0.62137
Return kilometers
End Function
Function convertKilometersToMiles() As Decimal
miles = kilometers * 0.62137
Return miles
End Function
End Module
|
|
|
|
|
What does "I can't get past putting in the number of units to use" mean? You are ignoring any user input except for the,
answer = Console.ReadLine() line. You would have to do something just like that to get the number of miles or kilometers that the user wants to convert....
|
|
|
|