Доступ - вставка строк без таблицы - PullRequest
0 голосов
/ 05 ноября 2018

У меня есть форма, где мне нужно, чтобы пользователь мог вводить данные в три столбца, эти данные будут между 10 и 200 строками.

Затем я хочу перебрать эти данные, чтобы иметь возможность преобразовать их в документ XML для передачи в экземпляр удаленного сервера SQL.

Эти данные будут вставлены из нескольких источников, в основном из документов Excel, поэтому в идеале я хочу использовать метод, позволяющий вставлять данные как таблицы.

Я хотел бы избежать использования временной таблицы для хранения этих данных, поскольку они будут использоваться несколькими пользователями, и у меня могут возникнуть проблемы с параллелизмом.

Если я добавлю таблицу данных, которая является несвязанной в качестве подчиненной формы, то будет разрешена только одна строка данных.

Есть ли способ связать подчиненную форму таблицы с переменной или использовать другой элемент управления, который позволит вставлять несвязанные данные?

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

Я собираюсь поделиться двумя решениями:

Во-первых, быстрое и грязное решение:

  1. Создание многострочного текстового поля
  2. Вставить к этому
  3. Разобрать результат

Обратите внимание, что при вставке текста он вставляется в файл 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 из буфера обмена, выполнив 2 шага:

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, вы можете получить XML-таблицу, вызвав GetClipboardSpreadsheetXML, а затем использовать XSLT для преобразования ее в нужный формат.

Для источников данных, отличных от Excel, вы можете использовать Формат HTML вместо XML Spreadsheet для извлечения HTML, если он доступен, а в противном случае вы можете использовать 1 (CF_TEXT) как ваш формат, а не перебирать все возможные форматы для извлечения простого текста из буфера обмена.

Подробнее об API буфера обмена можно узнать на Документах Microsoft

0 голосов
/ 05 ноября 2018

Ваша база данных должна быть разделена на фронтенд и бэкэнд. У каждого пользователя должен быть свой собственный интерфейс.

Тогда вы можете просто использовать временную таблицу во внешнем интерфейсе, и все это становится тривиальным.

При открытии формы вы делаете DELETE * FROM myTempTable.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...