Below is the code for a script to download a zip file from a website, but I get a compilation error that states 'expected identifier'.
Public Class DownloadAddrFile
Public Function DownloadFile(ByVal Addr As String, ByVal SaveAddrFile As String) As Boolean
Try
Dim WC As New System.Net.WebClient()
WC.DownloadFile(Addr, SaveAddrFile)
Return True
Catch ex As Exception
MessageBox.Show(ex.Message)
Return False
End Try
End Function
End Class
Call DownloadFile("http://data.gdeltproject.org/events/index.html/20171002.export.CSV.zip", "C:\Users\mwhiting\Documents\Zip_files\data.zip")
Any help on how to make this work would be great!
You can't call a method inside a Namespace.
Create an instance of Class DownloadAddrFile and for example inside a button-click call the method DownloadFile.
(The Call-keyword is usually not required)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim d As New DownloadAddrFile
d.DownloadFile("http://data.gdeltproject.org/events/index.html/20171002.export.CSV.zip", "C:\Users\mwhiting\Documents\Zip_files\data.zip")
End Sub
Related
I am in a project with multiple form.
I create a TicTacToe form here :
Private Sub MenuTicTacToe(ByVal sender As Object, ByVal e As System.EventArgs)
Dim page As Form = New TicTacToe
page.Show(Me)
End Sub
Here is a TicTacToe form:
Public Class TicTacToe
Public opponent as String
'Some code where user set opponent
Public Function Receive(S As String)
if string = opponent
'Some code
End Function
End Class
I would like to call my function Receive in my main form
If i do:
TicTactoe.Receive(S)
It call a instance of Receive where opponent does not exist.
I would like to find the oppened form of TicTacToe and call Receive
Thanks
Comments in line
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
page.Receive("Joe")
End Sub
'A form level variable to hold a reference to the instance of TicTacToe
'Although vb.net can use default instances, you have created an explicit
'instance of TicTacToe so you need to keep a reference if you want to
'refer to this instance.
Private page As TicTacToe
Private Sub MenuTicTacToe(ByVal sender As Object, ByVal e As System.EventArgs)
page = New TicTacToe()
page.Show(Me)
End Sub
Partial Public Class TicTacToe
Inherits Form
Public opponent As String
'Functions must be declared as a Type
'If you do not need a return value use a Sub
Public Function Receive(S As String) As String
Dim someString As String = ""
If S = opponent Then
'Do something
End If
'There must be a return Value
Return someString
End Function
End Class
Use this to show the form
Dim page As TicTacToe
Private Sub MenuTicTacToe(ByVal sender As Object, ByVal e As System.EventArgs)
page = New TicTacToe
page.Show(Me)
End Sub
Then you can use
page.Receive(S)
Edit
To use multiple forms
For Each f As TicTacToe in Application.OpenForms().OfType(Of TicTacToe)
f.Receive (S)
Next
In C#, you'd need a new instance, but as you are in VB, the compiler already does that for you.
What you are currently doing, is creating a new instance of the TicTacToe form and showing it:
Private Sub MenuTicTacToe(ByVal sender As Object, ByVal e As System.EventArgs)
Dim page As Form = New TicTacToe
page.Show(Me)
End Sub
But you don't save that instance anywhere. Then, in your next piece of code, you are using a different instance, which is the static one created by the compiler:
TicTacToe.Receive(S) // TicTacToe is the static instance
Therefore, you end up calling two different instances, which explains why there is no opponent set.
To get around this problem, do not create a new instance. In your Private Sub MenuTicTacToe, just use the instance created by the compiler, and you won't have this problem, just like this:
Private Sub MenuTicTacToe(ByVal sender As Object, ByVal e As System.EventArgs)
TicTacToe.Show(Me)
End Sub
Hope this helps.
I was beginning to think that I was getting good at VB.net, but not this one has me stumped.
Code looks something like this
Public Class MyServer
.....
Public myMQTTclient = New MqttClient("www.myserv.com")
.....
Private Sub Ruptela_Server(sender As Object, e As EventArgs) Handles
MyBase.Load
<some code>
StartMQTT()
<some more code>
MQTT_Publish(.....)
End Sub
Public Function StartMQTT()
' Establish a connection
Dim code As Byte
Try
code = myMQTTclient.Connect(MQTT_ClientID)
Catch ex As Exception
<error handling code>
End Try
Return code
End Function
Public Sub MQTT_Publish(ByVal DeviceID As String, ByVal Channel As String, ByVal ChannelType As String, ByVal Value As String, ByVal Unit As String)
Dim myTopic As String = "MyTopic"
Dim myPayload As String = "My Payload"
Dim msgId As UShort = myMQTTclient.Publish(myTopic, Encoding.UTF8.GetBytes(myPayload), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, False)
End Sub
As this stands it works 100% OK. The coding may seem a bit odd, but the intent is as follows :
a) create an object 'myMQTTclient' at module level so it has scope throughout the module
b) run StartMQTT() - It can still see the object.
c) within main program call MQTT_Publish many times - I can still see the object
Now the issue is this... it all goes well until "www.myserv.com" fails DNS, then the underlying winsock code throws an exception.
So ... I'm thinking - no problem - just wrap the declaration in a try block or check that www.myserv.com exists before launching the declaration.
Ah, but you can't put code at module level, it has to be in a sub or function.
Hmmm... now I'm stumped. There has to be a 'proper' way to do this, but I'll be darned if I can figure it out.
Anyone able to help ?
I'd follow the advice from #djv about declaring it just as you need it. To wrap that in a Try... Catch block you can do that in an Init method.
Public Class MyServer
Implements IDisposable ' As per djv recommendation which I second...
Private myMQQTclient As MqttClient
Public Sub Init()
Try
myMQQTClient = New MqttClient("<your url>")
Catch ex As Exception
' Do whatever
End Try
End Sub
' more code and implement the Dispose method...
End Class
You can then go on and implement the IDisposble interface to ensure that you release the resources.
Ok, I am not sure if I have the right library. But I found this Nuget package: OpenNETCF.MQTT which seems to have the class you are using.
I would do it this way
Public Class MyServerClass
Implements IDisposable
Public myMQTTclient As MQTTClient
'Private Sub Ruptela_Server(sender As Object, e As EventArgs) Handles MyBase.Load
' ' <some code>
' StartMQTT()
' ' <some more code>
' ' MQTT_Publish(.....)
'End Sub
Public Sub New(brokerHostName As String)
myMQTTclient = New MQTTClient(brokerHostName)
End Sub
Public Function StartMQTT()
' Establish a connection
Dim code As Byte
Try
code = myMQTTclient.Connect(MQTT_ClientID)
Catch ex As Exception
'<error handling code>
End Try
Return code
End Function
Public Sub MQTT_Publish(ByVal DeviceID As String, ByVal Channel As String, ByVal ChannelType As String, ByVal Value As String, ByVal Unit As String)
Dim myTopic As String = "MyTopic"
Dim myPayload As String = "My Payload"
Dim msgId As UShort = myMQTTclient.Publish(myTopic, Encoding.UTF8.GetBytes(myPayload), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, False)
End Sub
#Region "IDisposable Support"
Private disposedValue As Boolean
Protected Overridable Sub Dispose(disposing As Boolean)
If Not disposedValue Then
If disposing Then
myMQTTclient.Dispose()
End If
End If
disposedValue = True
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
End Sub
#End Region
End Class
And now you can see the usage when IDisposable is implemented, in a Using block:
Module Module1
Sub Main()
Using myserver As New MyServerClass("www.myserv.com")
myserver.StartMQTT()
myserver.MQTT_Publish(...)
End Using
End Sub
End Module
This makes it so your object is only in scope in the Using, and the object's Dispose method will automatically be called on End Using
I don't know what the base class was originally and why this was declared Private Sub Ruptela_Server(sender As Object, e As EventArgs) Handles MyBase.Load. It seems like it was possibly a form? You should keep your server code separate from Form code if that was the case. I suppose you could paste the Using into your form load, but then you would be blocking your UI thread. The referenced library has Async support so it might be a good idea to leverage that if coming from a UI.
I've made many assumptions, so I'll stop to let you comment and see how close relevant my answer is.
i wrote a program reading a com port for a signal, everything was working fine, but they wanted to make the application a service so i swapped the application type to 'windows service' and created a class and put everything in the form in there and i called the class in my Main() in the startup module. the line,
Me.Invoke(New myDelegate(AddressOf UPdateVariable), New Object() {})
in the class has invoke in red saying that, "'Invoke, is not a member of Moisture.Moisture.'" and the "Me" part of that line is no longer greyed out as it was in the form. it worked before dont know what made the difference.
this is the whole code for that class
Imports System
Imports System.IO.Ports
Imports System.Net.Mime
Public Class Moisture
Dim WithEvents serialPort As New IO.Ports.SerialPort
Public Delegate Sub myDelegate()
Public RawString As New System.Text.StringBuilder
Public value As String
Public Sub StartListening()
If serialPort.IsOpen Then
serialPort.Close()
End If
Try
With serialPort
.PortName = "COM3"
.BaudRate = 9600
.Parity = Parity.None
.StopBits = StopBits.One
.DataBits = 8
.Handshake = Handshake.None
.RtsEnable = True
End With
serialPort.Open()
Catch ex As Exception
End Try
End Sub
Private Sub serialPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort.DataReceived
Me.Invoke(New myDelegate(AddressOf UPdateVariable), New Object() {})
End Sub
Public Sub UPdateVariable()
With RawString
.Append(serialPort.ReadLine())
End With
If RawString.ToString().Count(Function(x As Char) x = "%"c) = 2 Then
PiTagUpdater(StringParser(RawString.ToString()))
RawString.Clear()
End If
End Sub
Public Function StringParser(RawString As String) As String
Dim Moisture = RawString
Dim value As String
Dim values As String() = Moisture.Split(New Char() {":"c})
value = values(values.Length - 1).Trim({" "c, "%"c})
Return value
End Function
Private Sub PiTagUpdater(Value As Decimal)
Try
Dim piserver As New PCA.Core.PI.PIServer(PCA.Core.Globals.Applications.Application("GENERAL").ConfigValues.ConfigValue("PI_SERVER_NAME").StringValue, PCA.Core.Globals.Applications.Application("GENERAL").ConfigValues.ConfigValue("PI_SERVER_UID").GetDeCryptedStringValue, PCA.Core.Globals.Applications.Application("GENERAL").ConfigValues.ConfigValue("PI_SERVER_PASSWD").GetDeCryptedStringValue, True)
Dim TimeStamp As DateTime = FormatDateTime(Now)
Dim RapidRingCrush = "M1:RapidRingCrush.T"
Try
piserver.WriteValue(RapidRingCrush, Value, TimeStamp)
Catch ex As Exception
MessageBox.Show("Error occured locating Pi Tag", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Application.Exit()
End Try
Catch ex As Exception
MessageBox.Show("Cannot connect to Pi Server")
End Try
End Sub
End Class
Me refers to the current object, in this case the instance of your class. Your class doesn't have an Invoke() method (like the error says), though anything that derives from System.Windows.Forms.Control does (for instance a Form).
Control.Invoke() is used to move the execution of a method to the same thread that the control was created on. This is used to achieve thread-safety.
Since you switched to a service it is fair to assume that you do not have a user interface, thus there's no need to invoke. Removing the Invoke() call and calling the method manually should be enough:
Private Sub serialPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort.DataReceived
UPdateVariable()
End Sub
EDIT:
As LarsTech says, you also have to switch the message boxes to some kind of logging methods. A Windows Service usually runs under a different account, which means that it cannot display a user interface to the current user.
I am making an application that reads values from a meter that is connected to my computer via a serial cable. When i press a button i send a command to the meter and after a few miliseconds i get a response back from the meter with the answer.
I am saving these values to a class that has properties init, so that i can access these values from anywhere.
So my problem is that when i try to get the values back it returns a 'nothing value', and its probably from the initialization i have that has a 'New' like this'Dim clsSavedValues As New clsSavedValues', so when i try to get the values from that property class i create a new instanse and that instanse is empty if am not mistaken.
Ill post the code below but here is how the code flows:
I have 3 classes. MainClass, ProtocolClass, PropertiesClass.
From main i call a method inside ProtocolClass, and that method sends a command to the meter. after a few miliseconds i get a call back inside ProtocolClass anf this method is called 'Private Sub SerialPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort.DataReceived' and it saves that return value to the PropertiesClass.
And after the DataReceived method is finished i go back to the MainClass and call another method to get the values from the PropertiesClass that i just saved but they return null. I know they are saved correctly because i can access them if i call them from within the ProtocolClass. But they are null from MainClass.
Here is my code:
MainClass
'Here i call the ProtocolClass
Private Sub btnGetLastTransaction_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetLastTransaction.Click
clsProtocol.GetLastTransaction(1, Integer.Parse(tbxTransactionPosition.Text))
End Sub
'Here i try to read the valies from PropertiesClass
Public Sub RetrieveMeterSerialNumber()
Dim clsSavedValues As New clsSavedValues
lblMeterSerialNumber.Text = clsSavedValues.SaveMeterSerialNumber
End Sub
ProtocolClass
Public Sub GetLastTransaction(ByVal destinationAddress As String, ByVal transactionNum As Integer)
clsSavedValues = New clsSavedValues 'Creating Instance of the properties class
Try
Dim v_bodyOfMessage As [Byte]() = {ASCIItoHEX("G"), _
ASCIItoHEX("r")}
Dim v_bytearray As [Byte]() = ConstructCommand(v_bodyOfMessage)
SendCommand(v_bytearray)
Catch ex As Exception
Console.WriteLine("Meter serial number button click exception: {0}", ex)
End Try
End Sub
Private Sub SerialPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort.DataReceived
If comOpen Then
Try
ReDim rx(rxPacketSize)
Console.WriteLine("RESPONSE")
For i = 0 To rxPacketSize - 1
readByte = SerialPort.ReadByte.ToString
Console.WriteLine(i.ToString & ": " & Conversion.Int(readByte).ToString)
rx(i) = Conversion.Int(readByte).ToString
If i <> 0 Then
If Convert.ToByte(rx(i)) = vDelimeterFlag(0) Then Exit For
End If
Next
DecodeResponse()
Catch ex As Exception
MsgBox("SerialPort_DataReceived Exception: " & ex.Message)
End Try
End If
End Sub
Private Sub GetMeterSerialNumber()
Dim i_startPosition As Integer = 5
Dim meterSerialNumber As String = GetRemainingPortionOfString(i_startPosition)
clsSavedValues.SaveMeterSerialNumber = meterSerialNumber
frmExplorer.RetrieveMeterSerialNumber() 'This is the call to the main class
End Sub
PropertiesClass
Public Property SaveMeterSerialNumber() As String
Get
Return _MeterSerialNumber
End Get
Set(ByVal meterSerialNumber As String)
_MeterSerialNumber = meterSerialNumber
End Set
End Property
I want to get the values from the PropertiesClass because ill get more than wan response from the meter and that causes thread issues and i cannot keep track with them. So i save the values in one class and then i want to access them all from that class.
Sorry for the long post, ask me anything you want for clarification
clsSavedValues in SerialPort_DataReceived() and in your Main Class RetrieveMeterSerialNumber() are two different objects (with same variable names but each 'new' create a new instance of clsSavedValues ) maybe you should pass the clsSavedValues var from protocol to Main as parameter.
Main :
Public Sub RetrieveMeterSerialNumber(clsSavedValues As clsSavedValues )
lblMeterSerialNumber.Text = clsSavedValues.SaveMeterSerialNumber
End Sub
Protocol :
Private Sub GetMeterSerialNumber()
Dim i_startPosition As Integer = 5
Dim meterSerialNumber As String = GetRemainingPortionOfString(i_startPosition)
clsSavedValues.SaveMeterSerialNumber = meterSerialNumber
frmExplorer.RetrieveMeterSerialNumber(clsSavedValues) 'This is the call to the main class
End Sub
or use a static property in your PropertiesClass
I created the following dll file to load image and draw image
Imports System.Drawing
Namespace GDI
Public Class ImageManager
Public Images As Dictionary(Of String, Image)
Public Sub LoadImage(Name As String, Path As String)
If Images.ContainsKey(Name) Then
Exit Sub
Else
Try
Dim i As Image = Image.FromFile(Path)
Images.Add(Name, i)
Catch ex As Exception
End Try
End If
End Sub
Public Sub RemoveImage(Name As String)
If Images.ContainsKey(Name) Then Images.Remove(Name)
End Sub
Public Sub DrawImage(Surface As Object, Name As String, Position As Point, Optional Size As Point = Nothing)
Try
If Images.ContainsKey(Name) Then
Dim G As Graphics = Surface.CreateGraphics
If Size.IsEmpty Then
G.DrawImage(Images(Name), Position)
Else
G.DrawImage(Images(Name), New Rectangle(Position.X, Position.Y, Size.X, Size.Y))
End If
End If
Catch ex As Exception
End Try
End Sub
End Class
End Namespace
I use the dll file in the form application to load the picture. I put both pictures in the project debug folder. But when I try to run the project. It gives me the ""System.NullReferenceException" in the dll file on
f Images.ContainsKey(Name) Then
Here is my code behind the form application:
Imports GFX.GDI
Public Class Form1
Private ImgMan As New ImageManager
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ImgMan.LoadImage("background", "Pic\background.jpg")
ImgMan.LoadImage("download", "Pic\downlaod.jpg")
End Sub
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
ImgMan.DrawImage(Me, "runningman", New Point(0, 0), New Point(Me.Width, Me.Height))
End Sub
End Class
You have not initialized the Images dictionary in the code above. Edit the declaration as below:
Public Images As new Dictionary(Of String, Image)