减小 vmware 虚拟机的硬盘容量,不是压缩

默认情况下,vmware 虚拟机的硬盘空间可以在 vmware 的虚拟机设置里调整大小,但只能『扩展』,却无法缩小。

当输入较小数字时,按钮变灰,无法点击。

 

问题:为什么要缩小虚拟机硬盘

一,vmware 的虚拟硬盘文件 *.vmdk 默认是动态分配空间的,没有数据的虚拟 “硬盘空间” 并不占用真实主机的实际硬盘空间。当虚拟机内需要储存更多数据时,对应的 vmdk 文件会相应增大,以便容纳新增的数据。但当虚拟机内的数据被清理时,已经增大的 vmdk 文件却不会自动缩小。随着虚拟机的不断使用,『只增大不缩小』的情况会逐渐严重,直到 vmdk 体积达到预设的虚拟机硬盘完整容量为止。

  • 向虚拟机内复制文件并随后删除。
  • 设置虚拟机快照并随后删除。
  • 安装各类软件而后卸载 / 利用快照恢复原样

等等各种情况都会增大 vmdk 体积。vmware 针对这种情况提供了 shrink disk(压缩硬盘)功能,也就是在虚拟机数据已经被清除后,整体扫描一遍 vmdk 文件,清理无效数据,缩小真实体积。但这也有两个麻烦:

  1. 因为膨胀永远存在,所以压缩也要经常进行,难免感觉在做无用功。
  2. Linux 下 shrink 功能有 bug,需要配合 dd 命令先以 0 数据充,相当于先撑大再缩小,耗时数倍。参考:第四条豆知识

二,很多情况下,我们安装虚拟机的用途都比较单一,比如干净 WinXP / Win7 测试软件,练习多个 Ubuntu Server 组集群,或在 Linux/Mac 主机上利用 Windows 虚拟机操作网银。虚拟机的实际硬盘占用也往往小于 vmware 的推荐值。这是实际需求方面及可操作方面。

三,强迫症 / 好奇 / 无理由。

于是,根据实际使用情况,适当降低虚拟机的硬盘容量,将『使用膨胀』的上限卡住,释放真实硬盘空间并避免经常的压缩操作,对时间和金钱都有好处。尤其是现在 SSD 逐步标配的阶段,虚拟机硬盘容量设置不当造成的浪费是很可观的。

问题:如何操作

我以一个当初决策不当分配了 40GB 硬盘空间的虚拟机 Windows XP 为例,重新调整的目标为 10GB。一般来说,全新安装的 Windows XP 大约占 4-5GB 空间,则我们还有约 5GB 空间可用来安装测试软件等,足够了。如果不够就自行酌情决定调整目标。

一、清理删除当前虚拟机下的所有快照,如果这些快照很重要不能删,那接下来的操作对你就没意义了。

二、确认虚拟机硬盘是拆分成多个文件的动态分配硬盘。本例子中,该虚拟机的所有文件放在 D:\Program files\Windows XP.vmwarevm 目录下。用 VSCode 打开虚拟机目录下和虚拟机同名的 *.vmdk 文件,如 『Windows XP.vmdk』。找到 # Extent description 部分,检查描述部分,一看就懂了。如图:

打开 vmdk 时几种可能的情况:

  • 如果有多行描述,并且每行写了 SPARSE ,这就是我们需要的类型,拆分+动态分配磁盘。直接跳过后续转格式步骤,进入修改分区步骤即可。
  • 如果有多行描述,但每行写的是 FLAT,则为拆分的预分配磁盘,需要转格式。
  • 只有一行描述,写的是 FLAT,则是单一文件预分配磁盘,也需要转格式。
  • 如果乱码或者提示打不开,则是单一文件动态分配磁盘,还是需要转格式。

VMWare 在新建虚拟机时会默认选择第一种类型,但玩家当初可能出于性能等考虑,选择了其它类型的虚拟硬盘。那么就需要使用 vmware 自带的一个命令行工具 vmware-vdiskmanager.exe转换成第一种类型。该工具在 vmware 安装目录下,默认为 “C:\Program Files (x86)\VMware\VMware Workstation\vmware-vdiskmanager.exe”。

转换方法:

该工具的命令行写法为:

工具名 参数1 源文件 参数2 参数3 目标名称
vmware-vdiskmanager -r(转格式) Windows XP.vmdk(例) -t(目的) 1(目的磁盘类型,1 为拆分+动态分配) newdisk.vmdk

该命令中, -r-t 1两部分不需要变化, 目标名称 随意,之后会改名覆盖源文件。 源文件名 根据实际情况变化,而 工具名 通常要带上路径。

所以完整的命令大约是如下样子:

回车以后开始执行转换:

转换完成以后,删除旧的 “windows XP.vmdk” 和多个关联文件 “windows XP-s0xx.vmdk”,然后把新的 newdisk.vmdk 重命名成 “windows XP.vmdk” 以替换。其它 newdisk-s00x.vmdk 不用变。

三,打开虚拟机,进入系统。

  • 在虚机机内,使用分区管理软件将硬盘分区缩小,并将空闲保留在右端,分区块保持在左端。我们的整体目标是从 40GB 缩到 10GB,则现在要多缩一点给后续操作留出余量。如图,暂时缩到 9GB。

  • Windows 7 以上系统,自带的磁盘管理就有『压缩卷』功能可以调整分区大小,WinXP 用的是 DiskGenius 免费版本。Win98 则需要寻找更古老的相应软件。
  • 中途可能需要重启虚拟机,无妨,调整完关闭虚拟机即可。

四,加减乘除:

再次打开 Windows XP.vmdk 文件,定位到 # Extent description 部分。这次重点放在第二部分数字内容上,经计算,该数字为每个分块文件对应虚拟硬盘的簇数量,每簇 512 Byte,2 簇 = 1KB。我们的目标容量为 10GB,也就是:

  • 10(GB)*1024(MB/GB)*1024(KB/MB)= 10485760 KB = 20971520 簇。

检查 # Extent description,前两个文件每个 8323072,则把第三行的数字改为

  • 20971520 – 8323072*2 = 4325376


并删掉后续各行及对应文件,我们就在 vmware 部分完成了虚拟机硬盘大小调整。

五,补足余量:

重开虚拟机。前次调整分区时,预留了 1GB 左右的余量。再次打开分区工具,把剩余未使用空间重新分配给各分区。

因为对计算机分区而言,由于存在分区表、启动扇区等原因,物理上的 10GB 硬盘空间在系统内表现是略小于 10GB 的,『内』『外』之间有差额,这对于虚拟机也一样成立。如果一开始就分区 10GB 而外部调整也等 10GB 的话,再次启动虚拟机就会报分区表错误,界时修改起来反而麻烦。现在这样按先预留余量,而后补足分区操作就没问题了。

六,清理死数据:

由于直接修改了描述文件,改小了簇数量,-s003.vmdk 里原本存于 4325376 之后的数据变成了永久的『死数据』。关闭虚拟机后,需要使用 vmware-vdistmanager -r <源.vmdk> -t 1 <目标.vmdk> 再作一次转换。虽说是转换,但目的却是清理死数据。清理完以后直接单独替换新旧 -s003.vmdk 即可。(想想为什么?)

————————————————-

相关细节:

  • 虚拟机为 Linux 系统时原理一样。利用 GParted 等分区工具,首先缩小使用分区,并调整未分区块到尾端。关机编辑 vmdk 描述,开虚拟机调整补分区足余量,再关机清理死数据即可。
  • 预分配类型的虚拟硬盘必须先 vdiskmanager 转类型,不能直接操作。追求性能的话在编辑完再转回去。不过追求性能的话应该上 SSD,一力降十会。
  • 编辑 .vmx 和 .vmdk 文件不要用 windows 自带的记事本。
  • 虚拟机备份直接复制整个目录即可。
  • 扩容不需要按本文操作,使用 vmware 自带功能即可。

HeidiSQL 的 SSH Tunnel 连接方式

heidisql_logo

HeidiSQL 是个挺好用的 Windows 下轻量级 MySQL / Ms SQL / PostgreSQL 客户端。官网地址:http://www.heidisql.com/ 。功能不写了,反正都差不多。 它提供的 SSH Tunnel 连接方式这里记一笔备忘 。

HeidiSQL 的 SSH Tunnel 连接方式其实就是先 SSH 连接到目标主机,再以目标主机的身份,连接到 MySQL 服务器。这有两种情况,一种是出于安全因素,数据库只允许本机或者有限几个 IP 访问,另一种是 MySQL 服务器和 SSH 目标主机在同一局域网内,而该局域网的多台机器只有 SSH 主机可以被外界直接连接。总之就是 MySQL 机无法被直接连接到,要通过 SSH 主机中转。

未命名

在中小网站中,数据库只允许 localhost / 127.0.0.1 连接是很常规的安全配置。但往往又存在需要后台操作数据的时候,于是有时会搭配 phpMyAdmin 这样的网页端方案,或者就是用 SSH Tunnel 这样的变通远程连接。

所以 HeidiSQL 的连接设置在选择网络类型为『MySQL (SSH Tunnel)』时也有所不同,除多出一个 『SSH隧道』选项页外,填写的参数也有变化。在 SSH Tunnel 模式下,设置页填写的是 SSH主机如何连接到 MySQL 服务器.

无标题

SSH 主机(不是本机)如何连接到数据库,很多中小网站的数据库只允许本地访问,则这里应当填写 127.0.0.1

而 SSH 隧道页填写的则是 本机如何连接到 SSH 主机,由于 SSH Tunnel 依赖 Putty 软件包中的 Plink.exe 程序,所以需要指定 plink.exe 的位置,或者索性复制一个到 HeidiSQL 同目录下。同时,SSH 除用户名密码连接方式外,还有公私钥系统的连接方式,需要通过 Putty 软件包的 puttygen.exe 将私钥文件转成 Putty 专用的 .ppk 格式。

无标题

本机如何连接到 SSH 主机

填写连接到 SSH 主机的用户名、密码,如果使用私钥文件的话,密码可以为空。

保存以后配置就完成了。并不需要去配置 Putty.exe 的任何内容。不知道为什么百度搜出来的好多博客都花了不少篇幅去写怎么配置 Putty,略扯淡。配置 Putty 与使用 HeidiSQL 并无直接关系。

 

一句话总结:

在普通模式下设置页填写的是运行 Heidi 的机器如何连接到目标 MySQL 服务器,而在 SSH Tunnel 模式下,需要先从运行 Heidi 的机器连接到 SSH 主机,再以 SSH 主机的身份连接到数据库服务器。

AWS Ubuntu 安装 PPTP VPN

AWS 现在提供新注册帐号一年免费服务,1台1G内存30G硬盘的 VPS,每月 15G 流量,可以用来架 VPS 或者博客主机,虽然流量不大,但日韩机房的速度很不错。

  1. 首先需要在主机配置面板的安全设置中,把入口流量防火墙的 1723 端口打开。否则配置正确也会被防火墙挡上。
  2. 安装 PPTPD 服务。
  3. 编辑 pptpd.conf 配置文件。
  4. 编辑 pptpd-options 配置文件。
  5. 编辑 chap-secrets 配置文件,添加 VPN 用户名和密码。
  6. 打开 IP 转发
  7. 需要重启服务:
  8. 添加 iptables 规则,这句根据服务商的不同会有不同,本句适用于 AWS
  9. 并添加到启动项中,以便服务器意外重启后继续正常工作:
  10. 配置完成,重启 pptpd 服务

Excel 计算缺陷与大数计算

Excel 很多时候可以当作一个简易的数学计算程序,代替 Mathematica 或者 Matlab 之类的专业软件进行一些不算太复杂的数值运算。但 Excel 的数据处理存在很多弱项,在遇到时需要相应作一些处理。

问题一:有效位数大约只有 15-16 位,更多的位数只会用 0 填充了。

1

精确计算的 2n 的尾数不会是 0,始终是 2→4→8→6→2…… 的循环,但从截图上可以看到,Excel 在计算 250 时,就遇到了有效位数问题,使得末尾出现了数字0。

关于问题一的应对:

从例子中可以看到,Excel 提供了 15 位的精度,这意味在在『千万亿』这个级别上 Excel 依然可以进行精确的计算。相当于以小数点后 4 位精度,即 0.0001 元 = 0.01 分 的精度下,处理九千亿人民币以下的财务数据。处理全国 GDP 的数据也可以精确到分,以米为精度可以让光跑一个月,以毫秒为精度覆盖三万多年。

但是如果你真觉得不够,就需要自己用公式实现进位,使用多个单元格作为『数字段』,来确保每个单元格内的数字长度不超过 15 位。

以 2为例,其计算由两部分组成:

最右一列公式为:

其中,Right 函数保证每个单元格只取结果的最右 12 位,让精度始终符合 15 位上限的要求。而 Text() 函数则保证当截取 12 位数字时,不会将原来在中间位置的 0 因为截取而成为首位 0 消失掉。例如,263 =  461,1686,0092,1369,3952,当截取 12 位时,会获得0092,1369,3952,如果不通过 Text() 函数保存首位的 0,则最后合并回去时就会产生错误。

左边每一列的公式均为:

这个公式同时适用于左边任意多列,使得只要电脑性能过关,尽可用尽 Excel  的所有列(一共 16384 列)。

公式略复杂,以 Y2 为例:

最外层 Text() 依然是为了保留首位 0。Value(Left()) 用于提取右边列的进位数字,即当前列的右侧列如果出现超过 12 位的数字时,则截取头部进到本列。Iferror() 用于检测是否进位。将进位数字和本列上一行数据乘二的结果相加后,再检测是否本列也多于 12 位,如果多则截取。公式引用关系如下:

I9N46D5M6%U}E@8IXWXS8CU

使用类似思想,可以精确进行一次数值变化不超过 1014 的大部分大数计算。需要注意的是,假如一次数值变化较大,则每单元格所能保留的位数就相应变小,不一定是 12 位了。

应对问题一的要点有二, 一是自行实行截取与进位,二是利用 Text() 公式特性,保留截断后的首位 0 不丢失。我通常把这种处理办法称为『大数多列化处理』。

 

 

问题二:数值上限大约在 21024-1,由于有效位数限制,实际上限更小一点,大约在 21023+21022+……+2971 ≈ 1.7977e308 左右。

2

这与问题一不同点在于,这个问题不关注精确展开,而更关注公式计算过程中的上限值。当然,使用问题一中的办法也能解决本问题中的部分情况,但对于更大的数字,例如用尽 Excel 所有列(16384列)也写不下的数字,大约 1016384*14 = 10229376,问题一中精确展开的解法就无能为力了。况且在实际展开中,在装满 Excel 前就早早会遇到内存和 CPU 瓶颈了。问题二的解法注重于在有限的计算资源下计算尽可能大的数字。

我们以计算 361 的阶乘为例,如果使用 Excel 公式直接输入 =Fact(361) 则只会得到一个 #NUM! 的结果。意即该计算的值或者计算过程中已经出现了超过 Excel 单元格所能容纳的最大值。

关于问题二的应对:

我们在 Excel 中准备三列数字,A 列为从 1-361 的展开。C1 公式为 =FLOOR.MATH(LOG10(A1)),B1 公式为 =A1/10^C1。

从 C2 起公式为:

从 B2 起公式为:

于是形成如下形式:

1~P8Q1T0%@[@S4J1CS4Y`U9

即 B C 两列形成了类似科学计数法的 b × 10 c 的数列。但不同之处在于,C 列的所有值全部相加,才是整个计算过程的最终解,如图:

EXWL~KE6X(5_2I4BLEN}%E5

即:361! = B361 × 10 SUM(C1:C361) = 1.43792325888489 × 10768,和上一篇博客对照一下,结果还是很精确的。

仔细观察 B、C 两列数值,其实原理就是每当一个新的 A 乘进来,都对结果作一次科学计数法处理,形成 b × 10 c 结构,确保每一次都有 1<b<10,然后把乘方 c 扔在一边最后再相加。

这一解法的关键在于在计算的每一步都即时处理,避免单元格数字过大而『爆掉』。通过这种方法,Excel 的可计算数域范围从大约 10308 变大到了大约 101,0000,0000,0000,0000,更大的数字则会产生 10 ~1000 倍甚至更大的误差。但如果对 C 列的数字再作问题一解法中的多列化处理,则可计算数上限大约会变成 1010229348 ,这里被迫用了幂的幂。这个数字相当大,并且实际不可能用到。早在这个极限之前,你的电脑内存估计就会挂掉。

 

 

当然,因为有 VBA,Excel 理论上也可以做复杂大数字计算,但考虑到学习成本和应用场景,不如学习 Mathematica 来得方便了。一般使用 Excel 做计算,都仅限于操作单元格和自带公式可以解决的问题。

VMWare 安装 Ubuntu 出现『默认声音设备无法打开』的原因与解决办法

Update: Ubuntu 16.04 系的解决了这个问题。此文终结。


无标题

这个 Bug 出现在几乎所有版本的 VMWare Workstation、VMWare Fusion 而且按原理来说似乎也会出现在 VirtualBox 上(未验证)。用户选择右键点击喇叭图标手动连接,则可以使用一段时间,Rhythmbox 之类的也可以正常播放声音,但只要打开声音设置或其它类似操作就又会断开。

遇到这种情况,可以先尝试在宿主机接上麦克风/耳麦,随便弄个录音设置,或者把普通耳机插头插进录音孔也行。对的,尽管实际上录不了音,但只要让录音孔插着东西就行。无标题

然后重启虚拟机,如果一切正常该提示不再出现,就继续往下看真·解决办法,如果依然不行,很抱歉你的问题不是这篇文章所能解决的。

 

这个问题的真正原因是:Ubuntu 默认会检测音频硬件设备,包括音频输入和输出两种设置,但 VMWare 不能正常反馈宿主机声卡的状态。感觉更多的是 Ubuntu 的锅,它没有检测设备存在就直接调用录音设备。

解决办法:

安装 pavucontrol 软件包,然后在 Term 中输入 pavucontrol 启动旧版的音量控制:

Ubuntu 64-2016-02-27-20-44-14

在音量控制界面,选择『配置』选项卡,选择『模拟立体声输出』,不要选任何带“输入”的项。然后注销用户再重新进入桌面。

Ubuntu 64-2016-02-27-20-45-50

 

以上,VMware Ubuntu 就可以正常出声了。

无标题

补充一个数组公式的实际应用

关于数组公式解释见这里:http://kaikai.info/excel-array-formulas-explaination/

补充一个实际应用里出现的公式

作用是在 A组数据的各项文字中寻找到第一条包含 B 组词汇的数据,如图:

matchindex

原理是这样的,将 find()函数数组化,令其在 A4:A27 中逐个寻找 C4 中的『愿望』两字。当找到匹配时,Find() 函数会返回一个具体数值,即『愿望』两字在被查找的字串中在第几个字符出现;当找不到匹配时,则Find() 函数会返回 #Value!。在数组化后,返回的数组大致为 {#Value!, #Value!, #Value!, #Value!, 2, #Value!, …, #Value!}。

再通过 if() 和 iserror() 判断这个数组中每个数的有效性,转为 {0, 0, 0, 0, 1, 0, …, 0}。

再通过 Match() 函数将数值 1 的位置找出来,即数组第 5 项。最后再通过 Index() 函数把原歌词中的第五句摘出来,并返回到屏幕上。

通过这个组合数组函数,可以查找某个词在多个单元格中的某一个出现过。

将函数改造成:

则通过复制粘贴数组公式,可以知道 C4 这个词分别在哪几句中出现过,而不限于仅仅找出第一句。

Excel 数组公式的概念解释

Excel 公式,本质就是输入原始数据,处理后再输出结果数据,放在公式的单元格里。

有些公式,输入是一个数据,输出也是一个数据,例如取整 int()、10 底对数 log()。若 A1=5.5,=Int(A1) 显示为 5。

有些公式,输入是一组数据,输出一个数据,例如 Sum。这一组数据整个是一个参数。若 A1:A5={1,2,3,4,5},输入公式 =Sum(A1:A5),显示为 15。A1:A5 数组是 Sum() 的一个参数。

有些公式,输入是两个参数,输出一个数据,例如 Match(A2,A1:A5)。两个参数,A1 是一个待查数据,参数二是被搜索的数组。

而数组公式,则是输入一组数据,输出一组数据

以 Match() 为例,Match 公式的形式为 =Match(lookup_value, lookup_array, [match_type]),其中 第三参数 match_type (查询模式)在本文讨论中忽略。则本文讨论的简化为 =Match(lookup_value 待查询数值, lookup_array 被搜索数组)

可以看到,一个 Match 公式一次只能在 lookup_array 里查找一个数值。而把 Match 公式改写为数组公式,并用 Ctrl+Shift+Enter 确认以后,实际公式则变成了 {=Match( lookup_value_array, lookup_array, [match_type] )}。

在公式里,本来应该是单一数值的地方,被替换成了一个数组,待查询数值 变成了 待查询数组。则 Excel 会自动响应 Ctrl+Shift+Enter 命令,把该公式拆分成多次分别执行,每次取待查询数组里的一项,单独给出一个结果,然后循环到该数组里的每个元素都被查询一遍。

例如,选择 C1:C5 单元格并在公式栏中输入 =Match( B1:B5, A1:A10, 0 ) ,按 Ctrl+Shift+Enter 回车。Excel 会自动内部展开五次 =Match() 查询,每次查询在第一个参数位分别填入 B1 – B5。即在 A1:A10 中分别查找 B1 – B5 的值,查 5 遍,并把 5 个结果分别放在对应的 C1:C5 单元格里。

array_match

所以:

1. 因为往往有多个输出结果,使用数组公式需要先选择好输出位置,再在公式栏写公式,写完用 Ctrl+Shift+Enter 确认。注意,这多个单元格包含的是『一个公式』。

2. 数组公式需要你在写公式时,把『一个数据』的参数改写为『一组数据』。(例子中 Match() 函数本来的 lookup_value 即『需要查找的值』改成了『需要查找的数组』。)Excel 会自动循环这个改写数组里的每一个数据,然后把公式计算结果填到对应的单元格里。

3. 数组公式修改起来较为费劲,经常会出现『不能更改数组的某一部分』,正确的方法是先按 Ctrl+/ 全选该数组公式的整体占用位置,然后再在公式栏进行修改。

4. 某些公式,例如 Sum()、Len() 使用数组公式和直接使用该公式往往没有区别。所以如果你见到某个教程在以 Sum 举例讲数组函数时就不用往下看了。百度搜出来有不少是这样的。

5. 一般来说,常用的数组计算 Excel 都已经提供了特定的函数,比如 Logest()、Frequency 等。如果返回的值有两个以上的,也通常都拆成了多个公式,比如线性回归的 Slope()、Linest()、Steyx() 等。当需要多个计算结果时,也无需使用数组公式,使用 Excel 的公式复制粘贴就可以完成绝大部分工作。上文的例子即是如此,选择 C1:C5 然后输入 Match() 数组公式,和先在 C1 输入普通的 Match 公式 =Match( B1, $A$1:$A:$10,0 ),然后把公式复制到 C2:C5 上,效果是一样的,后续处理起来还方便一些。

 

那么数组公式有什么用呢?

大部分情况其实没什么用,确实没什么用,所以很多人用了好久也没用过数组公式。哲学点地说,等到你需要用数组公式时,数组公式就有用了。

数组公式的最大特点是『输出的是一个数组』,所以它需要用多个单元格才能放下,同时,它可以作为数组参数供其它函数使用。所以数组函数最大的使用场景是通过复杂嵌套函数,实现更大程度的 Excel 自动化。

例如,去除重复单元格,可以使用 Alt+A+M 的『删除重复项』实现,但这样意味着每次数据更新,都需要重新进行人工操作,当处理步骤较多时,往往意味着后续步骤也需要重新操作。而使用数组公式,则可以一劳永逸地解决这个问题。

因为『删除重复项』本质上就是一个『输入一个数组,输出一个数组』的操作。在这个例子里,Match() 函数的第一个参数和两个 Row() 参数进行了相同的对应循环,并把每个计算结果填入相应的单元格里。

而另一个例子

则相当于把 A1 单元格中的每个字符都单拆出来。辅以其它公式嵌套,可以比较方便地计算诸如『若干个单元格一共包含多少个特定字符』之类的问题。

 

一句话总结:当你在使用 Excel 时,需要处理『处理若干个数据,过程中包含若干数据,结果也是若干个数据』时,在宏程序之外,还可以考虑使用数组公式。

Excel 自动打印表格份数/序号

#Update:

改进了。现在的样式如下:

0

第一步,先做一张报销单:

从自动化的角度来说,尽量采用公式帮助计算、限定单元格可输入的内容、以及设置单元格格式。在这张单据里,编号单元格为 K1

公式:

对于报销单而言,使用 =SUM() 和 =VLOOKUP() 通常就足够了,至多再加个 =SUMIF()、=COUNTIF() 就足以做出挺复杂的报销单了。

单元格格式:

选定单元格后 『右键→设置单元格格式』。标准的可以选择第三类货币格式,复杂的可以自行定义格式,使用#代表一个数位,使用0代表『当这个数位是最高位但为0时依然显示』。

step1-2

限定填充序列:

选定单元格后菜单栏选择『 数据→数据验证→数据验证』。允许序列,来源直接写入需要的内容,用英文逗号分隔。

step1-3

第二步,添加 Excel 的开发工具菜单:

依次点击菜单上的 『文件→选项→(跳出 Excel 选项窗口)→自定义功能区→☑开发工具』打钩。

step2

第三步,设置打印宏:

点击菜单上的 『开发工具→Visual Basic』,打开 VBA 面板,左侧双击 『ThisWorkbook』,把以下代码粘贴到出现的窗口内,然后关闭窗口

注意 K1 为这篇文章中的编号位置,其它表单需要相应调整。

step3

第四步,添加宏按钮:

点击『开发工具→插入→按钮(窗体按钮)』。

step4

然后用鼠标在 Excel 空白处拖出一个方块,当松开鼠标时,会自动跳出『指定宏』窗口,选择窗口内的『ThisWorkbook.PrintWithNumber』,然后确定。

step4-2

右键点击该按钮,选择『编辑文字』,修改为『打印报销单』。

step4-3

第五步,设置打印区域:

这一步是为了防止把按钮本身也打印出来。

全选需要打印的区域,选择菜单 『页面布局→打印区域→设置打印区域』。

step5

第六步,另存为 xlsm:

由于使用了 vba,必须把文件存为 xlsm 格式。(启用宏的 Excel 格式)

完工。


今天接到一个小任务,寥寥一记。

在 Excel 中,常见的一种需求是打印带份数号码的各种表单,例如报销单、外出单等。通常财务都会提供模板给员工自行填写,再由财务按入帐顺序统一写上序号。但当某人一次性要写几十份,或者说类似的需求,需要一次性打印 N 份时,有没有办法让打印的表格上自动带上序号?

解决办法需要依赖 Excel 中的宏程序,在 Excel 中按 Alt+F11 可以直接打开宏编辑器。或需要先通过『视图』→『宏』→『录制宏』,再经由编辑宏的办法来打开。

核心宏程序如下,一目了然:

E1 为需要填序号的单元格。程序先定义一个变量用来作为页码,然后不断用它替换指定单元格中的值,每替换一次就打印一张。这一方法硬要说有什么缺点的话,大概也就是打印任务数比较多,可能在几千份时会占用不少内存。

更完整的模板还需要在界面上做个按钮和两个输入框,以便让完全没有宏能力的财务也能定义起始和结束页码并打印。但今天这需求仅仅是帮助打印而不是做个新模版,所以这任务也就完成了不再搞复杂了。

样例下载 模板-日常费用报销表

等我有空了,来做个“就选它吧”网站

目录性质的软件推荐目录。网站目标是:“一个门类,只推一个软件,不给你选择”。

纯手工编辑,美工弄好看一点,弄个邮箱然后装高冷只收不回。如果数量多了,数据库还是得要一份的。

怎么推荐呢?

当你需要一个软件实现某个功能时,我只推荐一项。

比如 OCR 识别,就选 ABBYY 了,不需要考虑其它的;

图像处理,就选 Photoshop 了,我不管你是怎么弄到 Photoshop,反正我就推荐它了。大而全,功能都能实现,其它都是小意思;

自拍就美图秀秀了;

邮件,嘛,Outlook 和 Foxmail 都挺好的,但如果只推荐一项,我就推荐 Foxmail 了;

家谱软件,我看的最好的就是 Mac 下的 FamilyTree,再找找 Windows 下有什么好软件;

架博客,就用 WordPress 吧,功能较全,架设方便,甚至也有 VPS+Wordpress+域名 的打包解决方案。什么 Ghost、PivotX、Jekyll 都让 Geek 们自己折腾去;

等等。

可以理解作软件推荐版的好 123。

选择原则大概就是功能较全,或者效果最好。以不选择为前提,给出的就更倾向于较多功能的东西。效果好,指核心功能简单易用,上手顺利。

原因有二:

一、作为一个强迫症患者,我在需要软件解决一个问题时,往往会搜索该需求下的所有软件全部都试一遍,然后挑出我认为最舒适的一个软件,并为自己精妙的选择骄傲不已。后来发现,为了体验每一个软件,消耗掉的时间往往比实际使用软件能节约下来的时间更多。

比如我尝试过至少十来款记账软件,或者是主打简洁,或者是主打同步,但用来用去实足半年,真正的记帐这事却每次换 app 都重来一遍。最后买了个随手记,就不再去关心别的软件了,管它有多少功能,反正我就按天记个帐就行。

作为一个产品经理,去尝试很多软件,可以说是职业素养的一部分。但作为一个普通人,生活还是应当节省时间去做爱做的事情的。

二、实际工作中经常扮演救火兵的角色,有时也需要去解决并不擅长的问题,使用甚至没有听说过的软件的。这种时候有一个合适的推荐就很重要了。

所以这是一个“推己及人”的个人项目,虽然我一直说产品经理不是正常人,产品经理的自身需要往往不是正常需求。但在这个项目上,还是可以尝试一下普通人的角度看待问题的。

所以你看,再怎么着,这也是一份主观的选单,反映的倒不一定是我的个人口味,而更像是通过一份软件的表单,反过来表达我在产品经理这个身份上的选择直觉。

先记一笔,寒假大概就有时间去设计了。

http://chocolatey.org/ Windows 下的包管理器

chocolatey 是 Windows 下的包管理器,类似于 Linux 下的 apt,mac 下的 homebrew。

没错,windows 下的。

官方网站是 http://chocolatey.org/ ,已经写在标题里了。

虽然其实大部分可以 choco install 的包都是像 notepad++、Filezilla、Putty 等本身就可以下载安装包或者本身就是绿色软件,但也许也有一些像 Python、Ruby、Nodejs 之类让从 Linux/Mac 转过来的程序员们倍感亲切的软件包。不过要注意的是保持网络畅通,也就是说你还是需要一个 VPN,而不像 linux 那样可以方便地寻找到镜像源。

说实在的我在用了一段时间以后觉得有点行为艺术……o( ̄ε ̄*),其实最大原因是 CMD 窗口本身并不能提供太多的功能,不像 Linux/Mac 那样通过 ln 可以自定义命令,添加 Path 也比 linux 麻烦。

在图形操作系统下,用命令行去管理一大堆本身就有安装包有图形界面,可以双击图标调用关联程序打开,这些关联程序也大多有图形界面,实在有点违和。

所以最后我的结论是,如果你非要在 Windows 下尝试一下包管理器,Chocolatey 是个不错的选择。

安装方法:用管理员权限打开 CMD,输入以下字符(CMD 窗口的粘贴操作是 Alt+Space→E→P)

很有可能会开始下载一个 .msu 的安装包,应该是 PowerShell,安装完以后重启系统,用管理员权限打开 CMD,输入以下字符(CMD 窗口的粘贴操作是 Alt+Space→E→P)

…… 没错我写了两遍,实践证明确实需要两遍……ㄟ( ▔, ▔ )ㄏ

如果已经安装了 PowerShell,可以在 PS 里输入以下命令:

恭喜你,蛋疼去吧。