我有一个表单,需要用户能够在三列中输入数据,该数据将在10到200行之间。
然后,我希望对该数据进行迭代,以便能够将其转换为XML文档,以传递给远程SQL Server实例。
此数据将从多个来源粘贴,主要是Excel文档,因此理想情况下,我想使用允许像数据表一样本地粘贴的方法。
我想避免使用临时表来存储此数据,因为它将被多个用户使用,并且可能会遇到并发问题。
如果我添加一个未绑定的数据表作为子窗体,它将只允许单行数据。
是否有任何方法可以将数据表子窗体绑定到变量,或者使用另一种控件可以允许未绑定的粘贴?
答案 0 :(得分:1)
您的数据库应分为前端和后端。每个用户都应该有自己的前端。
然后,您只需在前端使用临时表,所有这些就变得微不足道了。
打开表单时,您进行DELETE * FROM myTempTable
。
答案 1 :(得分:1)
我将分享两种解决方案:
首先,快速而肮脏的解决方案:
请注意,粘贴文本会导致将其粘贴为TSV(制表符分隔的值)文件。如果您具有无法以TSV格式表示的值,则可能会导致问题。
第二,过于复杂的WinAPI剪贴板答案。我建议第一个答案适合新手用户,因为它更容易理解,第二个主要对高级用户有用
首先,我们需要对许多剪贴板函数,全局内存处理函数和字符串函数进行声明。我的声明与VBA6不兼容,但应与64位兼容:
'Global mem functions
Public Declare PtrSafe Function GlobalSize Lib "Kernel32" (ByVal hMem As LongPtr) As LongPtr
Public Declare PtrSafe Function GlobalLock Lib "Kernel32" (ByVal hMem As LongPtr) As LongPtr
Public Declare PtrSafe Function GlobalUnlock Lib "Kernel32" (ByVal hMem As LongPtr) As Boolean
'Clipboard functions
Public Declare PtrSafe Function GetClipboardData Lib "User32" (ByVal uFormat As Long) As LongPtr
Public Declare PtrSafe Function GetClipboardFormatNameW Lib "User32" (ByVal format As Long, ByVal lpszFormatName As LongPtr, ByVal cchMaxCount As Long) As Long
Public Declare PtrSafe Function OpenClipboard Lib "User32" (Optional ByVal hWndNewOwner As LongPtr) As Boolean
Public Declare PtrSafe Function CloseClipboard Lib "User32" () As Boolean
Public Declare PtrSafe Function EnumClipboardFormats Lib "User32" (ByVal format As Long) As Long
Public Declare PtrSafe Function CountClipboardFormats Lib "User32" () As Long
'String functions
Public Declare PtrSafe Function lstrcpyA Lib "Kernel32" (ByVal lpString1 As LongPtr, ByVal lpString2 As LongPtr) As LongPtr
然后,我们将分两步从剪贴板中获取XML电子表格:
Public Function GetClipboardSpreadsheetFormat() As Long
'Requires clipboard to be open, doesn't close it, returns 0 if not exists
Dim format As Long
Dim b As String
Dim l As Long
For l = 1 To CountClipboardFormats
b = String(100, vbNullChar) 'Initialize string buffer
format = EnumClipboardFormats(format) 'Get next format
GetClipboardFormatNameW format, StrPtr(b), 100 'Copy name to buffer
If Left(b, 15) = "XML Spreadsheet" Then
GetClipboardSpreadsheetFormat = format
Exit Function
End If
Next
End Function
Public Function GetClipboardSpreadsheetXML() As String
OpenClipboard 'Open (lock) the clipboard
Dim format As Long
format = GetClipboardSpreadsheetFormat
If format = 0 Then
Debug.Print "Spreadsheet data not available, display message here"
GoTo ExitHandler
End If
Dim hMem As LongPtr
hMem = GetClipboardData(format) 'Get handle to clipboard data
Dim memSize As LongPtr
memSize = GlobalSize(hMem) 'Get memory size
Dim buf() As Byte
Redim buf(0 To memSize - 1) 'Initialize buffer to hold XML
Dim memPtr As Long
memPtr = GlobalLock(hmem) 'Lock memory, get pointer to address
lstrcpyA VarPtr(buf(0)), memPtr 'Copy memory to buffer
GetClipboardSpreadsheetXML = StrConv(buf, vbUnicode) 'Convert ASCII string to unicode, return as result
ExitHandler:
If memPtr <> 0 Then GlobalUnlock (hMem) 'If memory pointer has been acquired, unlock global
CloseClipboard 'Close and unlock clipboard
End Function
由于您打算将电子表格转换为XML,因此可以通过调用GetClipboardSpreadsheetXML
来检索电子表格XML,然后使用XSLT将其转换为所需的格式。
对于非Excel数据源,您可以使用 HTML格式代替 XML Spreadsheet 来检索HTML(如果可用),否则可以使用1({{ 1}})作为您的格式,而不是迭代所有可能的格式以从剪贴板中检索纯文本。
您可以在Microsoft Docs上了解有关剪贴板API的更多信息