VBA专题12:详解GetAttr函数

excelperfect

有时候,你可能会发现了解正在与之交互的文件或文件路径的基本文件属性很有用。如果你读取文件内容后再将内容写回文件,那么知道原始文件是否为只读是重要的,在这种情况下,你的写入将失败,或者如果它是系统文件,在这种情况下写入也可能会失败,但是如果成功,可能会损坏系统。有时候,你可能只想检查一个字符串是否确实指向一个有效的文件或目录。

VBA的GetAttr函数将返回文件的基本属性。注意,由于它是一个函数,因此输出一个值;它不是文件对象的属性,不能写入GetAttr来更改文件的属性。同样,也不能使用此函数将文件设为只读或隐藏文件。

可能的属性

有7种可能的属性,对于给定的文件路径,可能不止一个,但也有一些相互排斥的属性。

下表所示是属性列表,来自Microsoft文档。

表中的第一列是VBA中的名称,相对于第二列中的值更易理解。在VBA程序中,可以将 vbXX名称与数字值互换使用。

输出

GetAttr函数输出的究竟是什么呢?唯一的输出是一个等于所有真实属性总和的整数值。对于你的特定输入,无论哪个属性为真,都将出现在该函数的输出中。

最简单的情况是文件只满足一个属性。假设文件myFile是隐藏的,且是该文件唯一的一个属性,从上表中可知,语句GetAttr(myFile)将返回2。

更复杂一点的是隐藏的系统文件。此时,必须在总和中包含4和2,因此输出为6:GetAttr(myFile) =vbHidden + vbSystem = 6。

隐藏目录的值是多少?vbHidden+ vbDirectory = 2 + 16 = 18。一个隐藏的只读系统文件的值是多少?vbReadOnly+ vbHidden + vbSystem = 7。

数字是2的幂的原因是:每个属性组合将总是给出一个唯一的数字,并且二进制加法的机制使按位运算更容易。

这种巧妙的技术意味着多个属性可以由一个数字表示而不会丢失任何信息,就像多个维度合并为一个。

分离属性

你可以查看包含所有可能输出的表并了解存在哪些属性。然而,大多数时候我们只对一个属性感兴趣。只读输入的可能值是1、3、5、35等。但是,测试每一个都会很麻烦。为了使之更容易,我们可以依靠二进制按位运算的优点。

要查看特定属性是否存在,需要使用AND运算符并将结果值设置为整数:

iReadOnly = GetAttr(myFile) And vbReadOnly

如果输出为零,则vbReadOnly不是此文件的属性。如果输出不是零,则存在vbReadOnly。下面是使用VBA的If-Then语句测试只读属性的完整示例:

Sub VBA_GetAttr_Demo()

Dim myFile As String

Dim iReadOnly As Integer

myFile ='C:\Public\MySpreadsheet.xlsm'

iReadOnly= GetAttr(myFile) And vbReadOnly

If iReadOnly <> 0 Then

'文件是只读的

Else

'文件不是只读的

End If

End Sub

下面的第二个示例测试路径是目录还是文件:

Sub VBA_GetAttr_Demo_Dir()

Dim myPath As String

Dim iDirAs Integer

myPath ='C:\Public'

iDir =GetAttr(myPath) And vbDirectory

If iDir<> 0 Then

'选择了目录

Else

'没有目录

End If

End Sub

无论文件路径末尾是否有斜杠,这都将起作用。

测试就是这么简单。要使用GetAttr函数,不需要更多信息,但如果想了解如何分解返回的总和数值,看下面的讲解。

按位与分解

那么我们如何测试一个数字是否真的是和的一部分呢?可以通过使用按位与来实现。

计算中的每个数字都由一串位表示,可以是on/true或off/false,通常分别表示为1和0。我们可以对这些位进行两种运算:AND和OR,它们来自数学逻辑。对于本文,重点是AND运算,其两边都必须为true/on/1,才输出1。如果一侧或两侧为false/off/0,则输出为0。

当我们查看2的位串表示时,我们得到10,其前导零可以无限添加,因此10 =00000010 = 0010,重要的部分是末尾跟随的零(和1)。

4的位串表示是100,8是1000,最好将这些读作“一零零”和“一零零零”,而不是“一百”、“一千”等。6是2+4,或110=010+100。下面是上述属性值的位串:

00 = 0000000

01 = 0000001

02 = 0000010

04 = 0000100

08 = 0001000

16 = 0010000

32 = 0100000

64 = 1000000

因为上表中的每个值都是2的幂,所以位串表示中的所有位除了其中一个外都为零。为此,将这些数字中的任何一个加在一起永远不会“翻转一位”并延续到下一列,因为每个数字都在其自己的列中完全表示。

要查看4是否是6的“一部分”,可以检查4中的每个1位是否在6中都有对应的1位。记住这是按位运算,因此我们需要逐列进行:

06 = 0000110

AND

04 = 0000100

xx = 0000100 <-- 按位输出,其中顶行和底行中的位均为1

在右边的第三列,也就是4的指定列,我们在6中有一个1位,按位AND运算符输出产生一个非零数,因此4,vbSystem,是6的一部分。如果我们有14(2+4+8),你能怎样计算来确定是否存在vbArchive?

如果总和的可能输入不是2的幂,则此技巧不起作用。

小结

VBA的GetAttr函数使用求和技术提供有关文件属性的信息,该技术为每个属性组合提供唯一编号。同时,VBA的GetAttr函数是一个函数,而不是文件属性,因此不能使用它来更改文件属性,只能使用它来确定存在哪些文件属性。

可以使用按位AND运算符确定是否存在特定属性。按位运算是逐位进行的,而不是将位串视为一个整体,并且属性的十进制表示中的间隙使按位AND能够检测属性是否为真。

注:本文整理自wellsr.com,供有兴趣的朋友参考。

(0)

相关推荐

  • Python 运算符重载

    https://www.cnblogs.com/hotbaby/p/4913363.htmlPython 运算符重载构造函数与表达式: __init__, __sub__ 常见运算符重载方法metho ...

  • Python学习手册(第4版).2

    先说坑,看懂为什么前面那么多没有运行出来吗? 这个是一段代码 原因很简单,这个代码是在缓存区呢,得Ctrl+S 平时是这样运行,其实代码直接从缓存区到右边得执行区.文本文件并不保存 重定向也正常~ 在 ...

  • 【知识汇总】初中数学基础知识详解:反比例函数

    初中数学基础知识详解及基础典型例题分析  --<初中数学典型题思路分析>附赠之一  反比例函数 典型例题见源文档. <初中数学典型题思路分析>书, 已被多个机构选为教学用书! ...

  • 【阅读理解】小说阅读考点专题 例题详解

    小说阅读 1 ★知识划重点★ 一.环境 小说中的自然环境描写与散文中的自然环境描写在景物特点及技巧等方面绝大部分是相同的.如果有区别的话,区别在于小说中自然环境描写的作用更尊重小说的文本特征,更贴切小 ...

  • 详解OFFSET函数

    excelperfect OFFSET函数可以给我们提供了一个对单元格区域的引用,从给定的起始单元格开始,移动到给定的单元格并扩展给定的高度和宽度. OFFSET函数的语法如下: =OFFSET(起始 ...

  • 实例详解SUBSTITUTE函数的常见用法

    SUBSTITUTE函数格式为: SUBSTITUTE(text,old_text,new_text,instance_num) text为需要替换其中字符的文本(或含有文本的的单元格的引用) old ...

  • 详解Python 函数如何重载?

    什么是函数重载?简单的理解,支持多个同名函数的定义,只是参数的个数或者类型不同,在调用的时候,解释器会根据参数的个数或者类型,调用相应的函数. 重载这个特性在很多语言中都有实现,比如 C++.Java ...

  • 详解RANK函数公式用法

    RANK(number,ref,[order]) 看着这个公式也不难,那我就稍微给各位可爱们讲解一下下好了.RANK函数的作用,就是返回某数字在一列数字中相对于其他数值的大小排名,number就是需要 ...

  • VBA专题11:详解UsedRange属性

    excelperfect UsedRange属性是Worksheet对象的一个有用的属性,可以返回工作表中已使用的单元格区域.实际上,根据UsedRange的意思,我们就可以明白,该属性代表工作表中已 ...

  • 热点预测12 | 人口迁移专题——押题预测及答题模板【详解】

    热点预测12 | 人口迁移专题——押题预测及答题模板【详解】

  • 电视选购12个重要参数详解,看完你就是专家,附:爆款推荐

    本内容来源于@什么值得买APP,观点仅代表作者本人 |作者:白云上的鱼 创作立场声明:分享电视选购知识,重要参数详解,轻松搞定电视选购. 目前电视的选择太多太多了,品牌百花齐放琳琅满目,各种高科技加成 ...