备忘录从 Access 数据库截断为 VBA 字符串

Posted

技术标签:

【中文标题】备忘录从 Access 数据库截断为 VBA 字符串【英文标题】:Memo truncated from Access database to VBA string 【发布时间】:2012-10-12 14:15:45 【问题描述】:

我的 Access (2003) 数据库中有一个备注字段,用于存储 Outlook 中文件夹的 EntryID(大约 750 个字符)。我正在尝试取回该 string 以使用以下代码将一些邮件移动到该文件夹​​ ID:

Dim myNameSpace As Outlook.NameSpace
Dim StoreID As String
Dim target as String 'This is the long EntryID string
Dim objMail as mailitem 'some mail

Set myNameSpace = Application.GetNamespace("MAPI")
StoreID = Application.GetNamespace("MAPI").folders("LiveLink").StoreID
Set dossier = myNameSpace.GetFolderFromID(target, StoreID)
objMail.Move dossier

target var 仅包含前 252 个字符,而不是在这种情况下为 748 个。有趣的是,如果没有其他可用的具有相同 ~255 个首字符的文件夹,Outlook 仍然会找到正确的文件夹。但在某些情况下,它会因为不止一个而崩溃。我正在使用 Recordset 从数据库中获取备忘录。这是我的 SQL:

SELECT EntryID FROM Folder

我终于找到了一些关于这种行为的信息:http://allenbrowne.com/ser-63.html。但是,如您所见,我没有在查询中使用任何联合或任何特定内容...

为什么它仍然被截断?

数据库中的原始备忘录/字符串:

00000000CE5B922DF5D7654C993FFDB4FF79A7A00100000057010000307E7E2D317E305C307E4C6976656C696E6B204851457E307E2D315C307E4C6976656C696E6B204851457E2D357E305C307E4C6976656C696E6B204851457E313233373235387E2D355C307E4C6976656C696E6B204851457E31303233363334317E313233373235385C307E4C6976656C696E6B204851457E31323930393430387E31303233363334315C307E4C6976656C696E6B204851457E31343539333439307E31323930393430385C307E4C6976656C696E6B204851457E31383735353632377E31343539333439305C307E4C6976656C696E6B204851457E3131363434333236317E31383735353632375C307E4C6976656C696E6B204851457E3131363434333236347E3131363434333236315C307E4C6976656C696E6B204851457E3131363434333238397E3131363434333236345C307E4C6976656C696E6B204851457E3131363434333330337E313136343433323839 P>

SQL 查询后截断的备忘录/对象/字段/字符串:

00000000CE5B922DF5D7654C993FFDB4FF79A7A00100000057010000307E7E2D317E305C307E4C6976656C696E6B204851457E307E2D315C307E4C6976656C696E6B204851457E2D357E305C307E4C6976656C696E6B204851457E313233373235387E2D355C307E4C6976656C696E6B204851457E3130323336333431 P>

【问题讨论】:

这是'SELECT EntryID FROM Folder'周围的代码?? Set rs = CurrentDb.Execute("SELECT EntryID FROM Folder"),然后是target = rs("EntryID") 多贴一点!!! msgbox(rs("entryID")) 呢? 我不是 SQL 专家,但我似乎可以使用其中的一些:bytes.com/topic/access/answers/…。但是我不知道它是否是最佳的,并且 EntryID 的长度并不总是相同,所以这可能是一个问题。 rs("EntryID") 仅包含前 251 个字符。问题不在于字符串或我的代码,而是直接从 SQL 查询中截断。 【参考方案1】:

如您的链接所示,这应该可以工作

Set rs = CurrentDb.Execute("SELECT Mid(EntryID,  1,250)  AS part1, " & _
       " Mid(EntryID,251,250)  AS part2," & _
       " Mid(EntryID,501,250)  AS part3," & _
       " Mid(EntryID,751,250)  AS part4," & _
       " Mid(EntryID,1001,250) AS part5 " & _
                          " FROM Folder;")
target = rs("part1") & rs("part2") & rs("part3") & rs("part4") & rs("part5")

【讨论】:

这就是我真正尝试的。出于某种原因,parts 为空。该吃饭了,我会在一个小时后回来看看有什么问题,但是你,我想它应该可以工作。 现在完美运行,谢谢。我不知道到底是什么问题,但现在可以了。【参考方案2】:

我已经实现了这个 c# 代码:

  private string GetMemoField(string TableName, string FieldName, string IdentityFieldName, string IdentityFieldValue, OleDbConnection conn)
    
        string ret = "";

        OleDbCommand cmd1 = new OleDbCommand("SELECT " + FieldName + " FROM “ + TableName + “ WHERE " + IdentityFieldName + "=" + IdentityFieldValue, conn);

                var reader = cmd1.ExecuteReader(System.Data.CommandBehavior.SequentialAccess);  // Create the DataReader that will get the memo field one buffer at a time

        if (reader.Read())
        
            long numberOfChars = reader.GetChars(/*Field pos*/ 0, 0, null, 0, 0);   // Total number of memo field's chars

            if (numberOfChars > 0)
            
                int bufferSize = 1024;
                char[] totalBuffer = new char[64*bufferSize];    // Array to hold memo field content

                long dataIndex = 0;

                do
                

                    char[] buffer = new char[bufferSize];   // Buffer to hold single read
                    long numberOfCharsReaded = reader.GetChars(0, dataIndex, buffer, 0, bufferSize);

                    if (numberOfCharsReaded == 0)
                    
                        ret = new string(totalBuffer,0, (int)numberOfChars);
                        break;
                    

                    Array.Copy(buffer, 0, totalBuffer, dataIndex, numberOfCharsReaded);     // Add temporary buffer to main buffer
                    dataIndex += numberOfCharsReaded;

                 while (true);
            
        

        return ret;
    

【讨论】:

欢迎来到 Stack Overflow!请考虑编辑您的帖子,以添加更多关于您的代码的作用以及它为什么会解决问题的解释。一个大部分只包含代码的答案(即使它正在工作)通常不会帮助 OP 理解他们的问题。 从数据库中检索数据的查询只返回一条记录和一个备注字段。带有“SequentialAccess”参数的“ExecuteReader”方法可以读取更多的 256 个字符。我每次都使用函数“GetChars”检索 1024 个字符。此外,此模式可用于使用函数“GetBytes”代替“GetChars”来读取 BLOB 类型的字段。

以上是关于备忘录从 Access 数据库截断为 VBA 字符串的主要内容,如果未能解决你的问题,请参考以下文章

为啥从 XML 导入 Access 数据库时数据会被截断

长文本(> 255 个字符)在 MS Access 2013 中导入和添加到现有表时被截断

从 .net 类型的数据集插入时,备注字段值被截断为大约 1000 个字符

如何使用 Access VBA 将具有默认值的未绑定文本框的值设置为空字符串

从 Excel 调用的访问 vba 函数导致返回不同的值

如何解决从Access到Word传递的FormFields VBA的字符限制