ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
Python自动化办公应用大全 Excel 2021函数公式学习大典 Kutools for Office 套件发布 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: aman1516

[讨论] 数组真的是"万能容器"吗?

[复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-11-22 23:00 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
这里暂且不考虑解决问题的方法、代码的优化、速度快慢、内存占用等问题,纯粹测试 “数组都还能装些啥”,
详见附件: 数组导出图片.rar (266.7 KB, 下载次数: 28)

TA的精华主题

TA的得分主题

发表于 2018-11-23 08:46 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
要事先申明  dim shp() as  picture ,图片 才真的在内存数组中,直接loadpicture 多张图片达到动画的效果。

如此 就不需要添加对象了 With shr(p, 1).ChartObjects.Add 再 paste ,这只是引用图片的 指针。





TA的精华主题

TA的得分主题

 楼主| 发表于 2018-11-23 20:20 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
zopey 发表于 2018-11-23 08:46
要事先申明  dim shp() as  picture ,图片 才真的在内存数组中,直接loadpicture 多张图片达到动画的效果。 ...

的确,数组存储的可能是“原始数据”,也可能是“路径地址”或“指针”或“映射“等“快捷方式”,又或处过的数据(最终成为“0”和“1”),但殊途同归,最终能得到想要的数据就数组就是好数组。
但从习惯理解上,原始数据、对象存入数组,才算真正的“内存数组”吧,真正理懂,看来还是要看看数据结构这门学课了。
因为想在多维数组中存储相关联的多种数据类型,所以不好做前期绑定,将整个数组定义成一个类型

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-11-23 20:51 | 显示全部楼层
把窗体也“装入”数组中,而激活窗框体,也只能通过 UserForms.Add 的方式,不知有无更好的方法,希望哪位老师指点一下:
  1. Sub arrtest6()

  2. '需引用 Microsoft Visual Basic For Application Extensibility
  3. '随意添加几个窗体

  4.     Dim wr(), Vbc As VBComponent, frm As Object
  5.     Dim n, s
  6.     For Each Vbc In ThisWorkbook.VBProject.VBComponents
  7.         If Vbc.Type = 3 Then
  8.            n = n + 1
  9.            's = s & Vbc.Name & "-" & Vbc.Type & Chr(10)
  10.            ReDim Preserve wr(1 To n)
  11.            Set wr(n) = VBA.UserForms.Add(Vbc.Name)
  12.          End If
  13.     Next
  14.     'MsgBox s
  15.     wr(2).Show 1
  16.     Erase wr
  17.    
  18. End Sub
复制代码


详见附件: 将窗体装入数组.rar (25.07 KB, 下载次数: 27)

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2018-11-23 21:31 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
数组就是一堆连续的数据,
对象数组里的每个元素只是引用地址,看上去对象放到数组里了,其实里面只是一个钥匙,并不是一般意义上的容器,用数组只是为了编写代码方便

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-11-24 13:33 | 显示全部楼层
hitzsf 发表于 2018-11-23 21:31
数组就是一堆连续的数据,
对象数组里的每个元素只是引用地址,看上去对象放到数组里了,其实里面只是一个 ...

实质性的容器,只能是电脑硬件了(硬盘、内存条),这里说的“容器”,只不过是打个比喻,但仍有区分,就如源文件与文件的快捷方式的区分。
对于将长二进制数据或长二进制文件读入数组内,不知怎样去理解,也只能当是一种处理过的数据了

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-12-9 14:01 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
结合应用,将TXT文档装入数组:
  1. Sub Arr_Txt()
  2. Dim sht As Worksheet, fso As Object, tmpLoc As Long
  3. Dim fr(), i&, j&, k&, n&, r&, mypath$, myname$
  4. Set sht = ActiveSheet
  5. r = sht.[A65536].End(xlUp).Row + 1
  6. sht.Range("A2:D" & r).ClearContents
  7. Set fso = CreateObject("Scripting.FileSystemObject")
  8. On Error Resume Next
  9. mypath = ThisWorkbook.Path & ""
  10. myname = Dir(mypath & "*.txt")
  11. Do While myname <> ""
  12.    If myname <> ThisWorkbook.Name Then
  13.       n = n + 1: ReDim Preserve fr(1 To 3, 1 To n)
  14.       fr(1, n) = myname     '文档名称
  15.       Set fr(2, n) = fso.GetFile(mypath & myname)     '文档对象
  16.       fr(3, n) = fr(2, n).OpenAsTextStream(1).ReadAll     '文档内容
  17.       fr(2, n).OpenAsTextStream(1).Close
  18.    End If
  19.    myname = Dir
  20. Loop

  21. For j = 1 To UBound(fr, 2)
  22.     tmpLoc = InStr(1, fr(3, j), vbCrLf)
  23.     Do Until tmpLoc = 0
  24.        sht.Cells(sht.Rows.Count, 1).End(xlUp).Offset(1).Value = _
  25.            Left(fr(3, j), tmpLoc - 1)
  26.        fr(3, j) = Right(fr(3, j), Len(fr(3, j)) - tmpLoc - 1)
  27.        tmpLoc = InStr(1, fr(3, j), vbCrLf)
  28.     Loop
  29.     sht.Cells(sht.Rows.Count, 1).End(xlUp).Offset(1, 0).Value = fr(3, j)
  30. Next
  31. r = sht.[A65536].End(xlUp).Row + 1
  32. sht.Range("A2:A" & r).Select
  33. Selection.TextToColumns Destination:=sht.Range("A2"), DataType:=xlDelimited, _
  34.         TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=True, Tab:=True, _
  35.         Semicolon:=False, Comma:=False, Space:=True, Other:=False, TrailingMinusNumbers:=True
  36.         
  37. Set fso = Nothing
  38. End Sub
复制代码

装入数组后,就可以结合数组的特性调用或处理 文档与数组的信息了

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-12-9 14:06 | 显示全部楼层
将TXT文档装入数组,详见附件:
将TXT文档装入数组.rar (47.8 KB, 下载次数: 16)

看到资料,还有通过“内存映像文件”的方法处理文档的,但VBA这方面的示例太少了,慢慢学习中……

TA的精华主题

TA的得分主题

发表于 2018-12-9 15:12 | 显示全部楼层
楼主的想法有些新鲜,一般用数组好像都是为了解决效率问题。
另外循环中用ReDim Preserve效率很低,先声明个足够大的,再弄个计数器,循环完了再ReDim Preserve

支持下楼主,看看这样弄在代码效率或方便上有没有提高

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-12-9 19:12 | 显示全部楼层
HHAAMM 发表于 2018-12-9 15:12
楼主的想法有些新鲜,一般用数组好像都是为了解决效率问题。
另外循环中用ReDim Preserve效率很低,先声明 ...

的确如是,先弄清楚,数组都能装什么后,再充分利用数组的特性提高效率与优化代码……

CSDN上看到一篇文章,使用内存映射文件的步骤:
1、创建或打开一个文件内核对象,该对象标识了我们想要用作内存映射文件的那个磁盘文件。
CreateFile();
2、创建一个文件映射内核对象,来告诉系统文件的大小以及我们打算如何访问文件。
CreateFileMapping();
3、告诉系统把文件映射对象的部分或全部映射到进程的地址空间中。
MapViewOfFile();
用完内存映射文件之后,必须执行以下三步进行清理。
1、告诉系统从进程地址空间中取消对文件映射内核对象的映射。
UnmapViewOfFile();
2、关闭文件映射内核对象。
CloseHandle();
3、关闭文件内核对象。
CloseHandle();

然后有个C+的示例:

  1. /************************************************************************/
  2. /*                        内存映射一                                    */
  3. /*程序演示了如何把一个已存在的文件映射到内存中,并倒转文件内容          */
  4. /*转载请注明文章来自:http://blog.csdn.net/windows_nt                    */
  5. //************************************************************************/

  6. #include <Windows.h>
  7. #include <tchar.h>
  8. #include <string.h>        // For _strrev
  9. #include <iostream>
  10. #include <CommDlg.h>

  11. typedef TCHAR *PTSTR;
  12. #define FILENAME  TEXT("FILEREV.DAT")

  13. BOOL FileReverse(PCTSTR pszPathname, PBOOL pfIsTextUnicode)
  14. {
  15.    *pfIsTextUnicode = FALSE;  // Assume text is Unicode

  16.    // Open the file for reading and writing.
  17.    HANDLE hFile = CreateFile(pszPathname, GENERIC_WRITE | GENERIC_READ, 0,
  18.       NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

  19.    if (hFile == INVALID_HANDLE_VALUE)
  20.    {
  21.       printf("File could not be opened.");
  22.       return(FALSE);
  23.    }

  24.    // Get the size of the file (I assume the whole file can be mapped).
  25.    DWORD dwFileSize = GetFileSize(hFile, NULL);

  26.    // Create the file-mapping object. The file-mapping object is 1 character
  27.    // bigger than the file size so that a zero character can be placed at the
  28.    // end of the file to terminate the string (file). Because I don't yet know
  29.    // if the file contains ANSI or Unicode characters, I assume worst case
  30.    // and add the size of a WCHAR instead of CHAR.
  31.    HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE,
  32.       0, dwFileSize + sizeof(WCHAR), NULL);

  33.    if (hFileMap == NULL)
  34.    {
  35.       printf("File map could not be opened.");
  36.       CloseHandle(hFile);
  37.       return(FALSE);
  38.    }

  39.    // Get the address where the first byte of the file is mapped into memory.
  40.    PVOID pvFile = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);

  41.    if (pvFile == NULL)
  42.    {
  43.       printf("Could not map view of file.");
  44.       CloseHandle(hFileMap);
  45.       CloseHandle(hFile);
  46.       return(FALSE);
  47.    }

  48.    // Does the buffer contain ANSI or Unicode?
  49.    int iUnicodeTestFlags = -1;   // Try all tests
  50.    *pfIsTextUnicode = IsTextUnicode(pvFile, dwFileSize, &iUnicodeTestFlags);

  51.    if (!*pfIsTextUnicode)
  52.    {
  53.       // For all the file manipulations below, we explicitly use ANSI
  54.       // functions because we are processing an ANSI file.

  55.       // Put a zero character at the very end of the file.
  56.       PSTR pchANSI = (PSTR) pvFile;
  57.       pchANSI[dwFileSize / sizeof(CHAR)] = 0;

  58.       // Reverse the contents of the file.
  59.       _strrev(pchANSI);

  60.       // Convert all "\n\r" combinations back to "\r\n" to
  61.       // preserve the normal end-of-line sequence.
  62.       pchANSI = strchr(pchANSI, '\n'); // Find first '\n'.

  63.       while (pchANSI != NULL)
  64.           {
  65.          // We have found an occurrence....
  66.          *pchANSI++ = '\r';   // Change '\n' to '\r'.
  67.          *pchANSI++ = '\n';   // Change '\r' to '\n'.
  68.          pchANSI = strchr(pchANSI, '\n'); // Find the next occurrence.
  69.       }

  70.    }
  71.    else
  72.    {
  73.       // For all the file manipulations below, we explicitly use Unicode
  74.       // functions because we are processing a Unicode file.

  75.       // Put a zero character at the very end of the file.
  76.       PWSTR pchUnicode = (PWSTR) pvFile;
  77.       pchUnicode[dwFileSize / sizeof(WCHAR)] = 0;

  78.       if ((iUnicodeTestFlags & IS_TEXT_UNICODE_SIGNATURE) != 0) {
  79.          // If the first character is the Unicode BOM (byte-order-mark),
  80.          // 0xFEFF, keep this character at the beginning of the file.
  81.          pchUnicode++;
  82.       }

  83.       // Reverse the contents of the file.
  84.       _wcsrev(pchUnicode);

  85.       // Convert all "\n\r" combinations back to "\r\n" to
  86.       // preserve the normal end-of-line sequence.
  87.       pchUnicode = wcschr(pchUnicode, L'\n'); // Find first '\n'.

  88.       while (pchUnicode != NULL) {
  89.          // We have found an occurrence....
  90.          *pchUnicode++ = L'\r';   // Change '\n' to '\r'.
  91.          *pchUnicode++ = L'\n';   // Change '\r' to '\n'.
  92.          pchUnicode = wcschr(pchUnicode, L'\n'); // Find the next occurrence.
  93.       }
  94.    }

  95.    // Clean up everything before exiting.
  96.    UnmapViewOfFile(pvFile);
  97.    CloseHandle(hFileMap);

  98.    // Remove trailing zero character added earlier.
  99.    SetFilePointer(hFile, dwFileSize, NULL, FILE_BEGIN);
  100.    SetEndOfFile(hFile);
  101.    CloseHandle(hFile);

  102.    return(TRUE);
  103. }


  104. void main()
  105. {
  106.         //当前目录下,必须是数字或字母且为回车结束,不然,转换出来是乱码
  107.         PTCHAR szPathname = _T("123.txt");

  108.         // Make copy of input file so that we don't destroy it
  109.         if (!CopyFile(szPathname, FILENAME, FALSE))
  110.         {
  111.                 printf("New file could not be created.");
  112.                 return;
  113.         }
  114.        
  115.         BOOL fIsTextUnicode;
  116.         if (FileReverse(FILENAME, &fIsTextUnicode))
  117.         {
  118.                 // Spawn Notepad to see the fruits of our labors.
  119.                 STARTUPINFO si = { sizeof(si) };
  120.                 PROCESS_INFORMATION pi;
  121.                 TCHAR sz[] = TEXT("Notepad ") FILENAME;
  122.                 if (CreateProcess(NULL, sz,
  123.                         NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
  124.                 {
  125.                         CloseHandle(pi.hThread);
  126.                         CloseHandle(pi.hProcess);
  127.                 }
  128.         }          
  129.         DeleteFile(FILENAME);

  130.         return;
  131. }
复制代码


不知用VBA如何实现
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2025-12-14 08:43 , Processed in 0.040324 second(s), 7 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表