I am using vb.net. I get a "too many arguments" error when I try to execute this code:
If System.IO.File.Exists("C:\Users\", My.User.Name, "Desktop\virus.exe")
Then
RichTextBox1.AppendText(RichTextBox1.Text & "virus.exe" & Environment.NewLine)
End If
Is there any way I can shorten this?
You have way too many arguments. File.Exists accepts only one.
You need to use ampersand for concatenation, not commas.
Use Imports to import namespaces to shorten your code and make it cleaner
Also, you appending entire text box again.
Below is fix for all your problems
Imports System.IO 'this will allow for shorter code
Dim myFile as String = "C:\Users\" & My.User.Name & "\Desktop\virus.exe"
If File.Exists(myFile) Then
' This will append only new text, not all of the existing text
RichTextBox1.AppendText("File: " & myFile & Environment.NewLine)
End If
Another way that makes this easy is by using Linq... Also you can use the My.Computer.FileSystem.SpecialDirectories.Desktop to go to the desktop and not have to worry about My.User.Name and concatenating strings ...
Here's a simple function - if you would want to use it again somewhere else...
Public Shared Function DoesFileExist(ByVal Directory As String, ByVal FileName As String) As Boolean
Return New System.IO.DirectoryInfo(Directory).GetFiles(FileName, IO.SearchOption.AllDirectories).Any
End Function
Usage Example
If DoesFileExist(yourdirectory, yourfilename) Then
MsgBox("Exists!")
End If
Or just in one line...
If New System.IO.DirectoryInfo(yourdirectory).GetFiles(yourfilename, IO.SearchOption.AllDirectories).Any Then RichTextBox1.AppendText blah blah...
Related
I have a VB.NET solution that stores data to a SQL database. I have written the first of several SSRS reports. Now I want to generate the reports from my VB.NET solution.
I have a subroutine that will generate the report,
Public Shared Sub GenerateReport(ByVal RptName As String, ByVal ParamArray Params() As Object)
Dim strPath As String = sqlSSRS + Replace(RptName, " ", "%20")
Dim _class As cParameters
'strPath += "&rc:Parameters=false&rs:Command=Render"
'strPath += "&rs:Command=Render"
For i As Integer = 0 To UBound(Params)
_class = DirectCast(Params(i), cParameters)
strPath += "&" & _class.ParamName & "=" & _class.Value
Next
System.Diagnostics.Process.Start(strPath)
End Sub
If I generate a path with no parameters the report will open in the default browser. So this works...
http://sqlServerName:80/Reports/report/ToolCrib/Toolbox%20by%20Installer
But neither this ...
http://sqlServerName:80/Reports/report/ToolCrib/Toolbox%20by%20Installer&#UserID=7&#ProjectID=20026&#ToolboxID=10&#ToolStatus=2
or this
http://sqlServerName:80/Reports/report/ToolCrib/Toolbox%20by%20Installer&UserID=7&ProjectID=20026&ToolboxID=10&ToolStatus=2
does.
I obviously have an issue passing parameters. In one case I don't need them but in other cases I want to provide them, which is why I wrote the GenerateReport routine with the optional Parameter array. Here is the error message I get which I know from past experience is sort of a catch all when MS doesn't "know" how else to classify an SSRS error.
The path of the item '/ToolCrib/Toolbox by Installer&UserID=7&ProjectID=20026&ToolboxID=10&ToolStatus=2' is not valid. The full path must be less than 260 characters long; other restrictions apply. If the report server is in native mode, the path must start with slash. (rsInvalidItemPath)
Any help will be greatly appreciated.
You path needs to use reportserver? instead of Reports/report when using parameters.
Try
http://sqlServerName:80/reportserver?/ToolCrib/Toolbox%20by%20Installer&UserID=7&ProjectID=20026&ToolboxID=10&ToolStatus=2
You could add a REPLACE:
strPath = Replace(strPath, "/Reports/report/", "/reportserver?/")
For more reading, you can check out
MS Docs url-access-parameter-reference
I want to write some VBA code that should parse MSForms-constant names (given as a string, like "fmTextAlignLeft") into their actual value. Since there is no native way to do so I was considering to put the name of the constant into a powershell code that will then be executed and return the result.
Private Sub ParseEnumByName(EnumConst As String)
Dim WScript As New WshShell
Dim PSCode As String
Dim Result
PSCode = "(some code)" & EnumConst & "(more code with exit $Value statement)"
Result = WScript.Run("Powershell -command """ & PSCode & """", 0, True)
ParseEnumByName = Result
End Sub
This should be feasible by iterating through all enums in the MSForms library and get the values out of them with something like
[System.Enum]::GetNames( [System.Windows.Forms.FormBorderStyle] ) or maybe something like explained here: How to convert a string to a enum?
The problem is that the System.Windows.Forms library contains totally different enums and typenames than the MSForms library available in VBA.
I tried to Add-Type -Path "C:\Windows\SysWOW64\FM20.DLL" where the MSForms library is stored but it returns an error saying the file or assembly or some related file could not be found.
How may I get a reference to MSForms in Powershell?
Edit: I have actually found a demi-native way in VBA (Excel VBA only) to solve this issue without passing values to external script hosts. Please see below.
Here's the function I figured out. So far it seems to work with all pre-defined enums and constants and also self defined enums in Excel. The function must be placed in a module!
Static Function ParseValue(StringValue) As Variant
Dim ParseValueBuffer As Variant
If IsEmpty(ParseValueBuffer) Then
ParseValueBuffer = 1
Application.Run ("'ParseValue " & StringValue & "'")
ParseValue = ParseValueBuffer
ParseValueBuffer = Empty
Else
ParseValueBuffer = StringValue
End If
End Function
Sub TestMe()
MsgBox "First line" & ParseValue("vbcrlf") & "Second line"
MsgBox ParseValue("fmTextAlignCenter") 'Should return "2" (if MSForms is referenced)
MsgBox ParseValue("rgbblue") 'Should return 16711680
End Sub
I am looking to find all instances of the exact string "Public" and replace it with " ' \n Public" (Add an empty comment above every Public declaration. )
I would also like to ignore any lines that are already commented out i.e. 'Public, and capture the whole line
What you want to do is
Load up the Find and Replace dialog and put Public in the Find what field and put '\nPublic in the Replace with field.
Check Match case and Use Regular Expressions
And away you go. The extension Multiline Search and Replace makes this a bit easier.
If you want normalized Windows-style line endings, you may want to replace with '\r\nPublic instead.
Visual Studio 2019 will allow you to replace Public with '\nPublic when using RegEx option. However if you don't have 2019 (or it doesn't work for some other reason), you can write some code to do it:
Put this method in your code and start debugging, then call the method
Imports System.IO
Module Module1
Public Sub foo()
Dim fileName = New System.Diagnostics.StackTrace(True).GetFrame(0).GetFileName()
Dim fileContents As String
Using sr = New StreamReader(fileName)
fileContents = sr.ReadToEnd().Replace(
"Pub" & "lic",
"'" & Environment.NewLine & "Pub" & "lic") ' String split so not replaced
End Using
Using sw = New StreamWriter(fileName, False)
sw.Write(fileContents)
End Using
End Sub
Sub Main()
foo()
End Sub
End Module
I think it's not natively possible with Visual Studio, but you can download a plugin like
https://marketplace.visualstudio.com/items?itemName=PeterMacej.MultilineSearchandReplace,
that provides such support.
I am creating a VB app which will "move" xls reports from a directory to a ReportSafe app. I am also working in an existing VB app which does just that, so I am using it for reference.
It isn't as simple as moving files from one directory to another, because ReportSafe requires an lpr command to tell it (ReportSafe) which file to pick up.
Here is what I have so far:
Imports System.IO
Module Module1
Sub Main()
''Declarations
Dim Files As ArrayList = New ArrayList()
Dim FileName As String
''Write All Files in *directory* to ReportSafe
Files.Clear()
Files.AddRange(Directory.GetFiles(*directory*))
For Each FileName In Files
Dim RPname As String
Dim RealName As String
RPname = FileName.ToString
RealName = "/"
RealName = RealName & RPname.Remove(0, 34)
Dim a As New Process
a.StartInfo.FileName = "C:\Windows\system32\lpr.exe"
a.StartInfo.Arguments = "-S*ServerName* -Plp -J" & Chr(34) & RealName & Chr(34) & " " & Chr(34) & RPname & Chr(34)
a.StartInfo.UseShellExecute = False
Next
End Sub
End Module
The whole lpr command/arguments are throwing me for a loop. I'm not sure if my question is specific to ReportSafe, and if that's the case, I may be out of luck here. I have pulled this code from the already existing app which moves reports to ReportSafe, and adjusted for my own use, but no luck so far.
FYI, I had to turn on LPR Monitor services to obtain to the lpr.exe
Questions:
What are the proper arguments to pass through to this lpr command?
Is there a problem with the logic that is causing the issue?
I continued to tinker and look at my reference code and discovered some flaws in logic:
For one, the report name I was passing did not include the complete file path.
Another thing is that I never started the process with a.Start(). Rookie mistakes for sure... haha
I have the following code that I am using to parse out a test file. I am getting variable conversion error in Sub Main() when I assign file = Read(). The return value of Read() is a TextFieldParser type. How do I assign the proper variable type to "file" so I can write the output to a text file?
Thanks!
Module Module1
Function Read()
Using MyReader As New FileIO.TextFieldParser("C:\Users\Colin\Desktop\Parse_Me.txt")
Dim currentRow As String
While Not MyReader.EndOfData
Try
currentRow = MyReader.ReadLine()
Console.WriteLine(Parse_me(currentRow))
Catch ex As FileIO.MalformedLineException
MsgBox("Line " & ex.Message &
" is invalid. Skipping")
End Try
End While
Return MyReader
MyReader.Close()
End Using
End Function
Function Parse_me(ByVal test As String)
Dim Set_1, Set_2, Set_3, Set_4, Set_5 As String
Dim new_string As String
Set_1 = test.Substring(0, 4)
Set_2 = test.Substring(7, 2)
Set_3 = test.Substring(11, 1)
Set_4 = test.Substring(14, 4)
Set_5 = test.Substring(20, 4)
new_string = Set_1 & " " & Set_2 & " " & Set_3 & " " & Set_4 & " " & Set_5
Return new_string
End Function
Sub Main()
Dim file As Object
file = Read()
FilePutObject("C:\Users\Colin\Desktop\Parse_Meoutput.txt", file)
End Sub
End Module
Here's how FilePutObject is supposed to work (example taken from MSDN documentation for FilePutObject):
Sub WriteData()
Dim text As String = "test"
FileOpen(1, "test.bin", OpenMode.Binary)
FilePutObject(1, text)
FileClose(1)
End Sub
The 1 act as an identifier for the file. Note also that the file name is passed to FileOpen before calling FilePutObject, and that FileClose is called afterwards. Also note that a string is being written to the file. I don't know which types of data are valid for being passed to FilePutObject, but FileIO.TextFieldParser is definitely not one of them (I just tried it).
Correct me if I'm wrong, but I'm pretty sure that FilePutObject is one of those carry-overs from VB6. If you're writing new code, I would rather use a Stream object for my I/O. For one, it's a lot more .Net-ish (i.e., type-safe, object-oriented, etc). And as far as usability goes, it's a lot clearer how a Stream works, not to mention it doesn't involve passing arbitrary integers as handles to functions in order to identify which file you'd like to work with. And to top it all off, a Stream works whether you want to write to a file, to the console, or send the data to another machine. To sum up, I would definitely look up the Stream class, some of its child classes (like FileStream, and whatever else appeals to you), and some associated types (such as the TextWriter class for conveniently writing text).
Change the definition of the function "read" to:
Function Read() as FileIO.TextFieldParser
and change the declaration of "file" in sub main to:
Dim file as FileIO.TextFieldParser
That way the data type of the function and assignment match.