How can get String UTF8 when connect from Excel to Postgresql? - postgresql

I connect excel to pgsql
1.install driver at:
https://www.postgresql.org/ftp/odbc/versions/msi/
2.Add a System DSN:
This is my code get database:
Public Function setDBConnectionPgsql() As Object
Set setDBConnectionPgsql = CreateObject("ADODB.Connection")
setDBConnectionPgsql.Open "DSN=PostgreSQL;Server=192.168.1.10;Port=5434;UserId=postgres;Password=123456;Database=test;"
End Function
Private Sub CommandButton1_Click()
Dim adoCn As Object
Dim dbRes As Object
Set adoCn = setDBConnectionPgsql()
Set dbRes = CreateObject("ADODB.Recordset")
dbRes.Open "SELECT * FROM mst_user", adoCn, 1, 2
Dim iRow As Integer
iRow = 1
Do While dbRes.EOF = False
ActiveSheet.Rows(iRow).Cells(1).Value = dbRes("user_id")
ActiveSheet.Rows(iRow).Cells(2).Value = dbRes("user_name")
iRow = iRow + 1
dbRes.moveNext
Loop
End Sub
Database is: "理宏"
But Result Excel display :逅・ョ・
If Text is English, it is ok.
How can get String UTF8 when connect from Excel to Postgresql?

The cause: i had install psqlodbc_07. i had fixed by install psqlodbc_10. it is ok.

Related

copy column to another different layout worksheet

I wish to copy data from Concur into my destination worksheet - Upload to Sun:
From Concur column J into UploadtoSun column D
From Concur column P into UploadtoSun column J
etc etc
My error message was the last sentence - Application defined or object defined error.
I'm not too sure how to write the last sentence. Can anyone assist ?
Dim ConcurLastRow As Long
Set Concur = ThisWorkbook.Worksheets("Concur")
Set UploadtoSun = ThisWorkbook.Worksheets("UploadtoSun")
Dim ConcurRngF As Range
Dim ConcurRngJ As Range
Dim ConcurRngK As Range
Dim ConcurRngO As Range
Dim ConcurRngP As Range
Dim UploadtoSunRngD As Range
Dim UploadtoSunRngF As Range
Dim UploadtoSunRngJ As Range
Dim UploadtoSunRngK As Range
Dim UploadtoSunRngL As Range
ConcurLastRow = Concur.Cells(Rows.Count, 1).End(xlUp).Row
UploadtoSunLastRow = Worksheets("UploadtoSun").Cells(Rows.Count, 4).End(xlUp).Offset(1, 0).Row
Set ConcurRngF = Concur.Range("F11:G" & ConcurLastRow)
Set ConcurRngJ = Concur.Range("J11:K" & ConcurLastRow)
Set ConcurRngK = Concur.Range("K11:L" & ConcurLastRow)
Set ConcurRngO = Concur.Range("O11:P" & ConcurLastRow)
Set ConcurRngP = Concur.Range("P11:Q" & ConcurLastRow)
Set UploadtoSunRngD = UploadtoSun.Range("D2:E" & UploadtoSunLastRow)
Set UploadtoSunRngF = UploadtoSun.Range("F2:G" & UploadtoSunLastRow)
Set UploadtoSunRngJ = UploadtoSun.Range("J2:K" & UploadtoSunLastRow)
Set UploadtoSunRngK = UploadtoSun.Range("K2:L" & UploadtoSunLastRow)
Set UploadtoSunRngL = UploadtoSun.Range("L2:M" & UploadtoSunLastRow)
Worksheets("UploadtoSun").Range("UploadtoSunRngD").Copy Worksheets("Concur").Range("ConcurRngJ").Value
you could do something like this
Sub Copydata()
Dim lastRow As Long
lastRow = Worksheets("Concur").Range("J:Z").Find("*", , , , xlByRows, xlPrevious).Row
'copy range
Worksheets("Concur").Range("J1:" & "J" & lastRow).Copy Destination:=Worksheets("UploadtoSun").Range("D1")
'copy entire column
Worksheets("Concur").Range("J:J").Copy Destination:=Worksheets("UploadtoSun").Range("K:K")
End Sub
how to get the last row Excel VBA - selecting range to last completely blank row

Mysqldatareader not returns records at all

I have the function in my class, which gets querystring and returns the two dimensional object array:
Public Function GetResultsBySql(ByVal sql As String) As Object(,)
Dim b(,) As Object = Nothing
Dim Command As New MySqlCommand(sql)
Dim rowCount As Int32 = -1
Using Conn As New MySqlConnection(Me.ConnectionString)
Command.Connection = Conn
Command.CommandTimeout = TimeOut
Try
Conn.Open()
Dim Dr As MySqlDataReader = Command.ExecuteReader
Do While Dr.Read
rowCount += 1
ReDim Preserve b(Dr.FieldCount - 1, rowCount)
For j As Int16 = 0 To Dr.FieldCount - 1
b(j, rowCount) = Dr(j)
Next
Loop
Return b
Catch ex As Exception
MsgBox(ex.Message.ToString, , "GetResultsBySql")
Return Nothing
End Try
End Using ' Connection
End Function
When I provide query which originally returns 156000 records. (In toad for mysql), object array contains only 71875 records.
It's due to DataReader limits or due to leak operating memory? No exception is thrown.
Any Ideas?

Export Table in Query to email VBA

I'm trying to export one of my queries to email using VBA in a table format. Similar to when you go to external data and click and E-Mail and it adds an attachment to outlook. Except I want it in the body. I put the following code in a button.
I found and made some changes to some code. This is what I have.
Private Sub Command5_Click()
Dim olApp As Object
Dim olItem As Variant
Dim db As DAO.Database
Dim rec As DAO.Recordset
Dim strQry As String
Dim aHead(1 To 4) As String
Dim aRow(1 To 4) As String
Dim aBody() As String
Dim lCnt As Long
'Create the header row
aHead(1) = "Part"
aHead(2) = "Description"
aHead(3) = "Qty"
aHead(4) = "Price"
lCnt = 1
ReDim aBody(1 To lCnt)
aBody(lCnt) = "<HTML><body><table border='2'><tr><th>" & Join(aHead, "</th> <th>") & "</th></tr>"
'Create each body row
strQry = "SELECT * From qry_email"
Set db = CurrentDb
Set rec = CurrentDb.OpenRecordset(strQry)
If Not (rec.BOF And rec.EOF) Then
Do While Not rec.EOF
lCnt = lCnt + 1
ReDim Preserve aBody(1 To lCnt)
aRow(1) = rec("Part")
aRow(2) = rec("Description")
aRow(3) = rec("Qty")
aRow(4) = rec("Price")
aBody(lCnt) = "<tr><td>" & Join(aRow, "</td><td>") & "</td></tr>"
rec.MoveNext
Loop
End If
aBody(lCnt) = aBody(lCnt) & "</table></body></html>"
'create the email
Set olApp = CreateObject("Outlook.application")
Set olItem = olApp.CreateItem(0)
olItem.Display
olItem.To = "email#email.com"
olItem.Subject = "Test E-mail"
olItem.HTMLBody = Join(aBody, vbNewLine)
olItem.Display
End Sub
When I run the code, I get a "Run-time error '3061' too few parameters. Expected 1."
If i click debug i get this highlighted in yellow. Anybody help would be greatly appreciated!
Edit
I tried a different approach which actually gave me the list in the body of the email. But it does it for the whole table instead of just the one record I want. This is what the SQL looks like of the query.
SELECT tblePMParts.[Part#], tblePMParts.PartDescription, tblePMParts.Qty, tblePMParts.Price
FROM tblePMParts
WHERE (((tblePMParts.WOID)=[Forms]![fmremail]![Text1]));
How would I go about adding the WHERE to the code below.
Private Sub Command4_Click()
'On Error GoTo Errorhandler
Dim olApp As Object
Dim olItem As Variant
Dim olatt As String
Dim olMailTem As Variant
Dim strSendTo As String
Dim strMsg As String
Dim strTo As String
Dim strcc As String
Dim rst As DAO.Recordset
Dim rs As DAO.Recordset
Dim db As DAO.Database
Dim qry As DAO.QueryDef
Dim fld As Field
Dim varItem As Variant
Dim strtable As String
Dim rec As DAO.Recordset
Dim strQry As String
strQry = "SELECT tblePMParts.[Part#], tblePMParts.PartDescription, tblePMParts.Qty, tblePMParts.Price " & _
"FROM tblePMParts; "
strSendTo = "test#email.com"
strTo = ""
strcc = ""
Set olApp = CreateObject("Outlook.application")
Set olItem = olApp.CreateItem(olMailTem)
olItem.Display
olItem.To = strTo
olItem.CC = strcc
olItem.Body = ""
olItem.Subject = "Please Quote the Following!"
Set db = CurrentDb
Set rec = CurrentDb.OpenRecordset(strQry)
If Not (rec.BOF And rec.EOF) Then
rec.MoveLast
rec.MoveFirst
intCount = rec.RecordCount
For intLoop = 1 To intCount
olItem.Body = olItem.Body & rec("[Part#]") & " - " & rec("PartDescription") & " - " & rec("Qty") & " - " & rec("Price")
rec.MoveNext
Next intLoop
End If
MsgBox "Completed Export"
Set olApp = Nothing
Set olItem = Nothing
Exit_Command21_Click:
Exit Sub
ErrorHandler:
MsgBox Err.Description, , Err.Number
Resume Exit_Command21_Click
End Sub
I got it working. Here is the code in case anybody needs it.
Private Sub Command5_Click()
Dim olApp As Object
Dim olItem As Variant
Dim db As DAO.Database
Dim rec As DAO.Recordset
Dim strQry As String
Dim aHead(1 To 3) As String
Dim aRow(1 To 3) As String
Dim aBody() As String
Dim lCnt As Long
'Create the header row
aHead(1) = "Part#"
aHead(2) = "Description"
aHead(3) = "Qty"
lCnt = 1
ReDim aBody(1 To lCnt)
aBody(lCnt) = "<HTML><body><table border='2'><tr><th>" & Join(aHead, "</th><th>") & "</th></tr>"
'Create each body row
strQry = "SELECT tblePMParts.[Part#], tblePMParts.PartDescription, tblePMParts.Qty, tblePMParts.Price " & _
"FROM tblePMParts " & _
"WHERE (((tblePMParts.WOID)=" & [Forms]![fmremail]![Text1] & "));"
Set db = CurrentDb
Set rec = CurrentDb.OpenRecordset(strQry)
If Not (rec.BOF And rec.EOF) Then
Do While Not rec.EOF
lCnt = lCnt + 1
ReDim Preserve aBody(1 To lCnt)
aRow(1) = rec("[Part#]")
aRow(2) = rec("PartDescription")
aRow(3) = rec("Qty")
aBody(lCnt) = "<tr><td>" & Join(aRow, "</td><td>") & "</td></tr>"
rec.MoveNext
Loop
End If
aBody(lCnt) = aBody(lCnt) & "</table></body></html>"
'create the email
Set olApp = CreateObject("Outlook.application")
Set olItem = olApp.CreateItem(0)
olItem.Display
olItem.To = "Email"
olItem.Subject = "Test E-mail"
olItem.HTMLBody = Join(aBody, vbNewLine)
olItem.Display
End Sub
Somewhere in your code, put a line that says
X = [Forms]![fmremail]![Text1]
Put a breakpoint in your code (hopefully you know how to do that?) on that line. When the code breaks, press F8 to step to the next line, and then type ?X in the Immediate Window. Or you can just hover your mouse over the line with the break point. The point is, you need to see what your code thinks [Forms]![fmremail]![Text1] is equal to. If it's null, you have a problem with your reference. In that case, you may need to add ".Value" or ".Text" to the end of it.
Another thing to check is your datatype for WOID. if it's text, you need to surround it with single quotes.
strQry = "SELECT tblePMParts.[Part#], tblePMParts.PartDescription, tblePMParts.Qty, tblePMParts.Price " & _
"FROM tblePMParts " & _
"WHERE (((tblePMParts.WOID)='" & [Forms]![fmremail]![Text1] & "'));"

simplest Unostructure that supports he getByName

In LibreOffice Basic sub I use a bunch of uno properties in an array. Which is the simplest Unostructure or UnoService that I must "embed" them, in order to use the getByName "function"?
Example:
dim props(1) as new com.sun.star.beans.PropertyValue
props(0).Name = "blahblah1"
props(0).Value = "blahblah1Value"
props(1).Name = "blahblah2"
props(1).Name = 3000
I want to be able to use something like:
b = props.getByName("blahblah2").Value
or something like (assuming I "assigned" them in a structure-like-object called "somestruct") :
b = somestruct.getprops.getByName("blahblah2").Value
As I understand that this can be done by creating a "UnoService" which supports the getByName and then, somehow, assigning these props to this service
Which is the "lightest" such service?
(I mean the service that uses less resources)
Thanks in advance.
Really supporting the interface XNameAccess is not as easy. The services which implement this interface are supposed using this interface for existing named properties, not for own created ones.
But you can use the service EnumerableMap to achieve what you probably want.
Example:
sub testEnumerableMap
serviceEnumerableMap = com.sun.star.container.EnumerableMap
oEnumerableMap = serviceEnumerableMap.create("string", "any")
oEnumerableMap.put("blahblah1", "blahblah1Value")
oEnumerableMap.put("blahblah2", 3000)
oEnumerableMap.put("blahblah3", 1234.67)
msgbox oEnumerableMap.get("blahblah1")
msgbox oEnumerableMap.get("blahblah2")
msgbox oEnumerableMap.get("blahblah3")
'msgbox oEnumerableMap.get("blahblah4") 'will throw error
msgbox oEnumerableMap.containsKey("blahblah2")
msgbox oEnumerableMap.containsValue(3000)
if oEnumerableMap.containsKey("blahblah4") then
msgbox oEnumerableMap.get("blahblah4")
end if
end sub
But starbasic with option Compatible is also able supporting Class programming like VBA does.
Example:
Create a module named myPropertySet. Therein put the following code:
option Compatible
option ClassModule
private aPropertyValues() as com.sun.star.beans.PropertyValue
public sub setProperty(oProp as com.sun.star.beans.PropertyValue)
bUpdated = false
for each oPropPresent in aPropertyValues
if oPropPresent.Name = oProp.Name then
oPropPresent.Value = oProp.Value
bUpdated = true
exit for
end if
next
if not bUpdated then
iIndex = ubound(aPropertyValues) + 1
redim preserve aPropertyValues(iIndex)
aPropertyValues(iIndex) = oProp
end if
end sub
public function getPropertyValue(sName as string) as variant
getPropertyValue = "N/A"
for each oProp in aPropertyValues
if oProp.Name = sName then
getPropertyValue = oProp.Value
exit for
end if
next
end function
Then within a standard module:
sub testClass
oPropertySet = new myPropertySet
dim prop as new com.sun.star.beans.PropertyValue
prop.Name = "blahblah1"
prop.Value = "blahblah1Value"
oPropertySet.setProperty(prop)
prop.Name = "blahblah2"
prop.Value = 3000
oPropertySet.setProperty(prop)
prop.Name = "blahblah3"
prop.Value = 1234.56
oPropertySet.setProperty(prop)
prop.Name = "blahblah2"
prop.Value = 8888
oPropertySet.setProperty(prop)
msgbox oPropertySet.getPropertyValue("blahblah1")
msgbox oPropertySet.getPropertyValue("blahblah2")
msgbox oPropertySet.getPropertyValue("blahblah3")
msgbox oPropertySet.getPropertyValue("blahblah4")
end sub
LibreOffice Basic supports the vb6 Collection type.
Dim coll As New Collection
coll.Add("blahblah1Value", "blahblah1")
coll.Add(3000, "blahblah2")
MsgBox(coll("blahblah1"))
Arrays of property values are the only thing that will work for certain UNO interfaces such as dispatcher calls. If you simply need a better way to deal with arrays of property values, then use a helper function.
Sub DisplayMyPropertyValue
Dim props(0 To 1) As New com.sun.star.beans.PropertyValue
props(0).Name = "blahblah1"
props(0).Value = "blahblah1Value"
props(1).Name = "blahblah2"
props(1).Name = 3000
MsgBox(GetPropertyByName(props, "blahblah1"))
End Sub
Function GetPropertyByName(props As Array, propname As String)
For Each prop In props
If prop.Name = propname Then
GetPropertyByName = prop.Value
Exit Function
End If
Next
GetPropertyByName = ""
End Function
XNameAccess is used for UNO containers such as Calc sheets. Normally these containers are obtained from the UNO interface, not created.
oSheet = ThisComponent.Sheets.getByName("Sheet1")
May UNO objects support the XPropertySet interface. Normally these are also obtained from the UNO interface, not created.
paraStyleName = cellcursor.getPropertyValue("ParaStyleName")
It may be possible to create a new class in Java that implements XPropertySet. However, Basic uses helper functions instead of class methods.
I think the serviceEnumerableMap is the answer (so far). Creating the values and searching them was much faster then creating props in a dynamic array and searching them with a for loop in basic.
(I do not "dare" to use "option Compatible", although I was a big fun of VB6 and VBA, because of the problems in code that maybe arise).
I used this code to test time in a form:
SUB testlala(Event)
TESTPROPS(Event)
' TESTENUM(Event)
MSGBOX "END OF TEST"
END SUB
SUB TESTENUM(Event)
DIM xcounter AS LONG
'b = now()
serviceEnumerableMap = com.sun.star.container.EnumerableMap
oEnumerableMap = serviceEnumerableMap.create("string", "any")
FOR xcounter= 0 TO 10000
oEnumerableMap.put("pr" & FORMAT(xcounter,"0000"), xcounter -10000)
NEXT
'b=now()-b
b = now()
FOR xcounter = 1 TO 5000
lala = Int((9000 * Rnd) +1)
g =oEnumerableMap.get("pr" & FORMAT(lala,"0000"))
'MSGBOX GetValueFromName(props,"pr" & FORMAT(xcounter,"0000"))
NEXT
b=now()-b
MSGBOX b*100000
END SUB
SUB TESTPROPS(Event)
DIM props()
DIM xcounter AS LONG
'b = now()
FOR xcounter= 0 TO 10000
AppendProperty(props,"pr" & FORMAT(xcounter,"0000"), xcounter -10000)
NEXT
'b=now()-b
b = now()
FOR xcounter = 1 TO 5000
lala = Int((9000 * Rnd) +1)
g = GetValueFromName(props,"pr" & FORMAT(lala,"0000"))
'MSGBOX GetValueFromName(props,"pr" & FORMAT(xcounter,"0000"))
NEXT
b=now()-b
MSGBOX b*100000
END SUB
REM FROM Andrew Pitonyak's OpenOffice Macro Information ------------------
Sub AppendToArray(oData(), ByVal x)
Dim iUB As Integer 'The upper bound of the array.
Dim iLB As Integer 'The lower bound of the array.
iUB = UBound(oData()) + 1
iLB = LBound(oData())
ReDim Preserve oData(iLB To iUB)
oData(iUB) = x
End Sub
Function CreateProperty(sName$, oValue) As com.sun.star.beans.PropertyValue
Dim oProperty As New com.sun.star.beans.PropertyValue
oProperty.Name = sName
oProperty.Value = oValue
CreateProperty() = oProperty
End Function
Sub AppendProperty(oProperties(), sName As String, ByVal oValue)
AppendToArray(oProperties(), CreateProperty(sName, oValue))
End Sub

itextsharp set bookmarks to fit page

I'm starting out with itextsharp and I've managed to answer all my questions but one:
How are bookmarks set to open to the fitpage zoom/view?
I apologize if this has already been answered elsewhere.
Here's my code if it helps.
//edit: Below is my working code. It has been modified using Bruno's example.
Public Sub MergePDFFiles(FileList As System.Collections.Generic.List(Of ModifiedItemForList), pdfName As String, pageCount As Integer)
Dim reader As PdfReader
Dim mergedPdf As Byte() = Nothing
Dim n As Integer
Dim page As Integer
Dim par As Paragraph
Dim pageMode As Integer
Dim pageLayout As Integer
Dim pageZoom As PdfDestination
Dim outlineZoom As PdfDestination
Dim pdfAction As PdfAction
Dim root As PdfOutline
Dim pdfOutline As PdfOutline
Using ms As New MemoryStream()
Using document As New Document()
Using copy As New PdfCopy(document, ms)
'Dim copy As New PdfCopy(document, ms)
document.Open()
root = copy.RootOutline
pageMode = copy.PageModeUseOutlines
pageLayout = copy.PageLayoutSinglePage
pageZoom = New PdfDestination(PdfDestination.FIT)
copy.ViewerPreferences = pageMode
pdfAction = pdfAction.GotoLocalPage(1, pageZoom, copy)
copy.SetOpenAction(pdfAction)
' For Each FilePath As KeyValuePair(Of String, String) In FileList ' .Count - 1
For i As Integer = 0 To pageCount - 1
' FilePath As KeyValuePair(Of String, String)
If File.Exists(FileList.Item(i).Value) Then
reader = New PdfReader(FileList.Item(i).Value)
' loop over the pages in that document
n = reader.NumberOfPages
page = 0
par = New Paragraph(FileList.Item(i).Key)
Debug.Print("FileList.Item(i).Key = " & FileList.Item(i).Key)
outlineZoom = New PdfDestination(PdfDestination.FIT)
pdfOutline = New PdfOutline(root, outlineZoom, par)
While page < n
copy.AddPage(copy.GetImportedPage(reader, System.Threading.Interlocked.Increment(page)))
End While
End If
Next
End Using
End Using
mergedPdf = ms.ToArray()
End Using
File.WriteAllBytes(pdfName, mergedPdf)
End Sub
Your input will be greatly appreciated,
Corbin de Bruin
If you want custom bookmarks, please don't use Chapter and Section, use PdfOutline instead. This is (of course) documented in chapter 7 of my book. If you need the C# port of the examples, take a look at the code examples for chapter 7, specifically CreateOutlineTree.cs, where instead of using PdfDestination.FITH (for Fit Horizontally) and a Y position, you just create a destination with PdfDestination.FIT (and no extra parameter):
new PdfOutline(root, new PdfDestination(PdfDestination.FIT), title, true);