I have made a program the receives an xml file via LAN (Net.Socket) and need to send a part of this XML data to a serial port (also to some labels)
When sending to the labels all goes well, because I'm using the following code (cross thread):
Delegate Sub SetlblScoreLine1TextInvoker(ByVal TextToDisplay1 As String)
Public Sub SetlblScoreLine1Text(ByVal TextToDisplay1 As String)
If lblScoreLine1.InvokeRequired Then
lblScoreLine1.Invoke(New SetlblScoreLine1TextInvoker(AddressOf SetlblScoreLine1Text), New Object() {TextToDisplay1})
Else
lblScoreLine1.Text = TextToDisplay1
End If
End Sub
I wanted to use this also for the serial port, but serialport1.invokerequired is not a member of systems.IO.ports.serialports.
This because not always the serial data is send correctly (cross thread??)
Any idea how I can solve this?
I'm not familiar with cross threads
Ok, this is how I send data to the serial port, hope this helps:
If SerialPort1.IsOpen = True Then
SerialPort1.Write("2" & strLine2 & vbLf & vbCr _
& "3" & strLine3 & vbLf & vbCr _
& "4" & strLine4 & vbLf & vbCr)
SerialPort1.Write("Cxx234xdx" & vbCrLf & vbCr)
End If
If you need more information, please let me know
Related
I have a function (bastardised from Ron DeBruin's Website) that saves the active or selected sheet as a pdf and sends it as an attachment in outlook. It still works for everyone I've given it to but lately, it is not working on my PC. I keep getting the error message as if VBA cannot save the file (due to the path being invalid or the name being used already and not wanting to overwrite)
Running on various PCs that are either running on Windows 10 or 7 (I'm on Win10) I've tried changing the save file path & the filename in the code to something more simple and I still have the same issues. I tried the file on another machine running windows 10 and had no issues. I've also tried checking Microsoft Add-Ins and everything is fine.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub RDB_Worksheet_Or_Worksheets_To_PDF_And_Create_Mail()
Dim FileName As String
If ActiveWindow.SelectedSheets.Count > 1 Then
MsgBox "There is more than one sheet selected," & vbNewLine & _
"be aware that every selected sheet will be published"
End If
'Call the function with the correct arguments
'Tip: You can also use Sheets("YourSheetName") instead of ActiveSheet in the code(sheet does not have to be active then)
FileName = RDB_Create_PDF(Source:=ActiveSheet, _
FixedFilePathName:="C:\Users\" & Environ("Username") & "\Documents\Container Shipment Reports\" & (Range("G4").Value) & ".pdf", _
OverwriteIfFileExist:=True, _
OpenPDFAfterPublish:=False)
'For a fixed file name use this in the FixedFilePathName argument
'FixedFilePathName:="C:\Users\Ron\Test\YourPdfFile.pdf"
If FileName <> "" Then
RDB_Mail_PDF_Outlook FileNamePDF:=FileName, _
StrTo:="XXXXXX.XXXXXXX#XXXXX.com.au", _
StrCC:="XXXXXX.XXXXXXX#XXXXX.com.au; XXXXXX.XXXXXXX#XXXXX.com.au", _
StrBCC:="", _
StrSubject:="Container Shipment Report " & (Range("G4").Value) & ".", _
Signature:=True, _
Send:=False, _
StrBody:="<body>Hello,</body><br>" & _
"<body>Please see the attached Container Shipment Report# " & (Range("G4").Value) & " from " & (Range("E4").Value) & "." & _
"<br><br>" & "Thank you.</body>"
Else
MsgBox "Not possible to create the PDF, possible reasons:" & vbNewLine & _
"Microsoft Add-in is not installed" & vbNewLine & _
"You Canceled the GetSaveAsFilename dialog" & vbNewLine & _
"The path to Save the file in arg 2 is not correct" & vbNewLine & _
"You didn't want to overwrite the existing PDF if it exists"
End If
Application.Quit
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
This should convert to PDF, attach to an email, send the email and then close Excel. At the moment I am just getting the MsgBox response from the code, "Not possible to create PDF, possible reasons: etc".
(there is also a function to stop the excel file saving as it is meant to be a blank template.) As I said this seems to be an issue only on my machine but as it works on other computers I'm thinking there's no issue with the code.
I have an issue, have an AutoCAD file with a ton of data links and would like to update only the data links related to a speciffic table.
Simmilar to the functionality of selecting a table with data links, right clicking and selecting Update Table Data Links.
i have the following code:
Private Sub Update_table_data_link(tblRef As AcadTable)
ThisDrawing.SendCommand "DATALINKUPDATE" & vbCr & "U" & vbCr & "K" & vbCr
End Sub
It works but updates all the data links in the drawing (which is a problem) so a perfect solution would either let me get what links are associated to tblRef
and change the line to:
ThisDrawing.SendCommand "DATALINKUPDATE" & vbCr & "U" & vbCr & "D" & vbCr & "datalink_name_from_tblRef" & vbCr
or directly send the command to update the links to tblRef
After much digging around and a lot of help, here is the answer:
Private Sub Update_table_data_link(tblRef As AcadTable)
ThisDrawing.SendCommand "DATALINKUPDATE " & vbCr & "U" & vbCr & Ent2lspEnt(tblRef) & vbCr & vbCr
End Sub
Public Function Ent2lspEnt(entObj As AcadEntity) As String
'Designed to work with SendCommand, which can't pass objects.
'This gets an objects handle and converts it to a string
'of lisp commands that returns an entity name when run in SendCommand.
Dim entHandle As String
entHandle = entObj.Handle
Ent2lspEnt = "(handent " & Chr(34) & entHandle & Chr(34) & ")"
End Function
note that "Update_table_data_link" has a table as input
I'm trying to read and write a list of properties from files (mainly doc and xls), like Title, Author, Tags or Comments. I can easily get basic attributes, but not these extended ones.
GetDetailsOf used to work ( https://technet.microsoft.com/en-us/library/ee176615.aspx?f=255&MSPPError=-2147217396 ) however now it stops dead at index 6.
According to the Docs ( https://learn.microsoft.com/en-us/windows/desktop/shell/shellfolderitem-extendedproperty ) .ExtendedProperty is supposed to be able to read attributes, but it doesn't return most of them. For example Author(s), which is even cited as an example in the link above (There are two ways to specify a property. The first is to assign the property's well-known name, such as "Author"), returns nothing.
Is there another way?
Test script for a single file:
Sub PrintDocumentProperties()
With CreateObject("Shell.Application").Namespace("D:\VBA")
MsgBox .GetDetailsOf(.Items.Item("derp.xlsm"), 5) & vbNewLine & _
.Items.Item("derp.xlsm").ExtendedProperty("Date modified") & vbNewLine & _
.Items.Item("derp.xlsm").ExtendedProperty("Type") & vbNewLine & _
.Items.Item("derp.xlsm").ExtendedProperty("Size") & vbNewLine & _
.Items.Item("derp.xlsm").ExtendedProperty("Author") & vbNewLine & _
.Items.Item("derp.xlsm").ExtendedProperty("Authors")
End With
End Sub
I'm working with legacy code here and I'm not sure how much I could or should change, but I have code that looks for something like "SIC CODE 4000"
However the data html database I pull it from (we use a copy and paste) has updated their code to have:
"SiC CODE
4000"
Currently the code is:
Const strSic = "SIC Code "
However I now need it to add line breaks.
I tried modifying the code to say:
Const strSic = "SIC Code" & Chr(10) & Chr(10) & Chr(10)
But I get a compile error saying "Constant expression required"
I tried using "SIC Code \n\n\n" but maybe I'm not thinking the right character for line break.
Any suggestions?
The code for a new line is vbNewLine:
Const strSic = "SIC Code" & vbNewLine & vbNewLine & vbNewLine
Update:
To be a bit more detailed see the VBA constants:
vbNewLine = Chr(13)+Chr(10) on Windows and Chr(13) on Mac
vbCr = Chr(13)
vbLf = Chr(10)
So if you only need Chr(10) you should use vbLf (like Excel Hero's answer).
Try this:
Const strSic = "SIC Code" & vbLf & vbLf & vbLf
Yes vbNewLine is the correct code : )
Given a pre-configured ODBC System DSN, I'd like to write a function that gracefully tests that connection using VBA.
Private Function TestConnection(ByVal dsnName As String) As Boolean
' What goes here?? '
End Function
Edit: To clarify, the System DSNs are pointing to external SQL Server 2005 databases, with Windows NT authentication.
One approach I've tried is to send some random query to the target database and catch the error. If the query works, return true. If there's an error then return false. This works just fine but it feels...kludgy. Is there a more elegant way, especially one that doesn't rely on On Error Goto ?
Note: It's a legacy Access 2000 database I'm working on, so any solution can't have any Access 2007 or 2003 dependencies. I'd like to make it generic to VBA, but if there's a simple way in Access that's fine too.
Much obliged for any advice.
Dim cnn As ADODB.Connection
Dim canConnect as Boolean
Set cnn = New ADODB.Connection
cnn.Open "DSN HERE"
If cnn.State = adStateOpen Then
canConnect = True
cnn.Close
End If
Msgbox canConnect
EDIT: DSN Format could be "DSN=MyDSN;UID=myuser;PWD=myPwd;"
Look this for connection strings
I'm too late to give you a useful answer to your question, but I came here because I wanted to see if StaCkOverflow has a better answer than the code I'm currently using to test ADODB connections.
...It turns out that the answer is 'No', so I'll post the code for reference: someone else will find it useful.
Coding notes: this isn't a generic answer: it's a method from a class encapsulating the ADODB.Connection object, and it assumes the existence of object 'm_objConnect'.
TestConnection: a VBA Class method for publishing debugging information for an ADODB.Connection object
This prints out the connection string, the current status, a list of ADODB errors (if any) and a full listing of the onnection's named properties.
Public Sub TestConnection()
On Error GoTo ErrTest
Dim i As Integer
If m_objConnect Is Nothing Then
Debug.Print "Object 'm_objConnect' not instantiated."
Else
Debug.Print m_objConnect.ConnectionString
Debug.Print "Connection state = " & ObjectStateString(m_objConnect.State)
Debug.Print
If m_objConnect.Errors.Count > 0 Then
Debug.Print "ADODB ERRORS (" & m_objConnect.Errors.Count & "):"
For i = 0 To m_objConnect.Errors.Count
With m_objConnect.Errors(i)
Debug.Print vbTab & i & ":" _
& vbTab & .Source & " Error " & .Number & ": " _
& vbTab & .Description & " " _
& vbTab & "(SQL state = " & .SqlState & ")"
End With
Next i
End If
Debug.Print
Debug.Print "CONNECTION PROPERTIES (" & m_objConnect.Properties.Count & "):"
For i = 0 To m_objConnect.Properties.Count - 1
Debug.Print vbTab & i & ":" _
& vbTab & m_objConnect.Properties(i).Name & " = " _
& vbTab & m_objConnect.Properties(i).Value
Next i
End If
ExitTest:
Exit Sub
ErrTest:
Debug.Print "Error " & Err.Number & " raised by " & Err.Source & ": " & Err.Description
Resume Next
End Sub
Private Function ObjectStateString(ObjectState As ADODB.ObjectStateEnum) As String
Select Case ObjectState
Case ADODB.ObjectStateEnum.adStateClosed
ObjectStateString = "Closed"
Case ADODB.ObjectStateEnum.adStateConnecting
ObjectStateString = "Connecting"
Case ADODB.ObjectStateEnum.adStateExecuting
ObjectStateString = "Executing"
Case ADODB.ObjectStateEnum.adStateFetching
ObjectStateString = "Fetching"
Case ADODB.ObjectStateEnum.adStateOpen
ObjectStateString = "Open"
Case Else
ObjectStateString = "State " & CLng(ObjectState) & ": unknown state number"
End Select
End Function
Share and enjoy: and watch out for line-breaks, helpfully inserted where they will break the code by your browser (or by StackOverflow's formatting functions).
There no magic function that will test this without actually connecting and trying an operation.
If you feel bad about the random query part - you can query the system tables
For Access
SELECT TOP 1 NAME FROM MSysObjects
For SQL Server
SELECT TOP 1 NAME FROM sysobjects
If you merely have to test that the database server is actually available, this can be done, despite what is being said here that it cannot.
In that case, you can attempt to open a TCP connection to the specific server and port.
The default instance of SQL Server, for example, listens on TCP port 1433. Attempting a simple TCP connection in VBA will tell you if it succeeds or not. Only if that is successful I would query using the ODBC connection.
This is a lot more graceful and efficient. It would remove any "gross" error from your ODBC test code. However, as I said, it is only applicable if you need to test for the mere existence/availability of the database server instance.