Dot(.) after the file permission flags in Redhat

Phenomenon:

$ rsh coolnjmcl033 'ls -l /opt/cool/tools/lib/COOLvirtenv'
ls: cannot access /opt/cool/tools/lib/COOLvirtenv: Permission denied

[root@coolnjmcl033 etc]# ls -l /opt/cool/tools/lib/COOLvirtenv
-rwxr-xr-x. 1 cool cool 29852 Jul 22 03:16 /opt/cool/tools/lib/COOLvirtenv

According to http://www.redhat.com/archives/rhelv6-list/2010-December/msg00076.html,

From "info ls":

      Following the file mode bits is a single character that specifies
     whether an alternate access method such as an access control list
     applies to the file.  When the character following the file mode
     bits is a space, there is no alternate access method.  When it is
     a printing character, then there is such a method.

     GNU `ls' uses a `.' character to indicate a file with an SELinux
     security context, but no other alternate access method.

     A file with any other combination of alternate access methods is
     marked with a `+' character.

In order to make files located on one server can be accessied by other servers, SELinux should be disabled. In order to disable SELinux,  refer to How to Disable SELinux.

RPC - Program not registered in RHEL6.1

I just installed Redhat Enterprise Linux 6.1 on one HP server. Following error met when rup it on other servers:

$rup coolnjmcl033
rup:coolnjmcl033: RPC: Program not registered

SOLUTION:

1)        check if all nfs related services are working:

[root@coolnjmcl033init.d]# rpcinfo -p
   program vers proto   port  service
    100000   4   tcp    111 portmapper
    100000   3   tcp    111 portmapper
    100000   2   tcp    111 portmapper
    100000   4   udp    111 portmapper
    100000   3   udp    111 portmapper
    100000   2   udp    111 portmapper
    100011   1   udp    875 rquotad
    100011   2   udp    875 rquotad
    100011   1   tcp    875 rquotad
    100011   2   tcp    875 rquotad
    100003   2   tcp   2049 nfs
    100003   3   tcp   2049 nfs
    100003   4   tcp   2049 nfs
    100227   2   tcp   2049 nfs_acl
    100227   3   tcp   2049 nfs_acl
    100003   2   udp   2049 nfs
    100003   3   udp   2049 nfs
    100003   4   udp   2049 nfs
    100227   2   udp   2049 nfs_acl
    100227   3   udp   2049 nfs_acl
    100005    1  udp  51310  mountd
    100005    1  tcp  60605  mountd
   100005    2   udp 42799  mountd
   100005    2   tcp 44201  mountd
   100005    3   udp 49544  mountd
   100005    3   tcp 49098  mountd
   100024    1   udp 37035  status
   100024    1   tcp 60898  status
   100001    3   udp  1008  rstatd
   100001    2   udp  1008  rstatd
   100001    1   udp  1008  rstatd

If there is no running rstatdservice , start it by
service rstatd start

Accordingto RHEL 6 RUP manual:

    rup: RPC: Program not registered

 

The rpc.rstatd(8) daemon has not been started on the remote host.

 

2)  check if package rusers-server-*and rusers-*
are installed: rpm –qa|greprusers. If not, install it and then restart service rstatd.

 

PS:

Other userful commands:

  1. rup localhost
  2. service rstatd status

According to
New Featuresin RHEL6
,

1.ext4 file system is introduced.
2. xen is removed and kernel virtualization machine (KVM) is introduced.
3. neat command is removed.
4. portmap service is removed.
5. iscsi is introduced, which supports forSAN.
6. rpmbuild is available, which is used to create our own rpms.
7. File encyption is added.
8. palimpsest is available for disk management.
9. Virtual machine will run only on 64bit processors.
10. postfix service is recommended insteadof sendmail service.

 

Accordingto
Chapter 12. Network File System (NFS)
,

The portmap service wasused to map RPC program numbers to IP address port number combinations inearlier versions of Red Hat Enterprise Linux. This service is now replaced by rpcbind inRed Hat Enterprise Linux 6 to enable
IPv6 support. For more information aboutthis change, refer to the following links:

Required Services

nfs
service nfs start starts the NFS server and the appropriate RPC processes to service requests for shared NFS
file systems.
nfslock
service nfslock start activates a mandatory service that starts the appropriate RPC processes which allow
NFS clients to lock files on the server.
rpcbind
rpcbind accepts port reservations from local RPC services. These ports are then made available (or advertised)
so the corresponding remote RPC services can access them. rpcbind responds to requests for RPC services and
sets up connections to the requested RPC service. This is not used with NFSv4.
The following RPC processes facilitate NFS services:
rpc.mountd
This process receives mount requests from NFS clients and verifies that the requested file system is currently exported. This process is started automatically by the nfs service
and does not require user configuration.
rpc.nfsd
rpc.nfsd allows explicit NFS versions and protocols the server advertises to be defined. It works with the
Linux kernel to meet the dynamic demands of NFS clients, such as providing server threads each time an NFS client connects. This process corresponds to the nfs service.
lockd
lockd is a kernel thread which runs on both clients and servers. It implements the Network
Lock Manager
 (NLM) protocol, which allows NFSv2 and NFSv3 clients to lock files on the server. It is started automatically whenever the NFS server is run and whenever an NFS filesystem is mounted.
rpc.statd
This process implements the Network Status Monitor (NSM) RPC protocol, which notifies NFS clients when an NFS server is restarted without being gracefully brought down. rpc.statd is
started automatically by the nfslockservice, and does not require user configuration. This is not used with
NFSv4.
rpc.rquotad
This process provides user quota information for remote users. rpc.rquotad is started automatically by the nfsservice
and does not require user configuration.
rpc.idmapd
rpc.idmapd provides NFSv4 client and server upcalls, which map between on-the-wire NFSv4 names (which are
strings in the form of user@domain)
and local UIDs and GIDs. For idmapd to function with NFSv4, the/etc/idmapd.conf must
be configured. This service is required for use with NFSv4, although not when all hosts share the same DNS domain name.

c++filt

c++filt
decodes (demangles) low-level names into user-level names so that the linker can keep these overloaded functions from clashing.

You
may use
c++filt to demangle
the symbols.


$ c++filt _ZNSt8ios_base4InitD1Ev
std::ios_base::Init::~Init()

You may try adding
-lstdc++ to your link command
to resolve the issue.


c++filt
  

     c++filt [-_|--strip-underscores]
             [-j|--java]
             [-n|--no-strip-underscores]
             [-p|--no-params]
             [-s format|--format=format]
             [--help]  [--version]  [symbol...]
     

The C++ and Java languages provides function overloading, which means that you can write many functions with the same name (providing each takes parameters of different types). All C++ and Java function names are encoded into a low-level assembly label (this
process is known as mangling). The c++filt 1 program does the inverse mapping: it decodes (demangles) low-level
names into user-level names so that the linker can keep these overloaded functions from clashing.

Every alphanumeric word (consisting of letters, digits, underscores, dollars, or periods) seen in the input is a potential label. If the label decodes into a C++ name, the C++ name replaces the low-level name in the output.

You can use c++filt to decipher individual symbols:

     c++filt symbol
     

If no symbol arguments are given, c++filt reads symbol names from the standard input and writes the demangled names to the standard output. All results are printed on the standard output.

-_
--strip-underscores
On some systems, both the C and C++ compilers put an underscore in front of every name. For example, the C name foo gets the low-level name _foo. This option removes the initial underscore. Whether c++filt removes
the underscore by default is target dependent. 
-j
--java
Prints demangled names using Java syntax. The default is to use C++ syntax. 
-n
--no-strip-underscores
Do not remove the initial underscore. 
-p
--no-params
When demangling the name of a function, do not display the types of the function's parameters. 
-s format
--format=format
c++filt can decode various methods of mangling, used by different compilers. The argument to this option selects which method it uses:

auto
Automatic selection based on executable (the default method) 
gnu
the one used by the GNU C++ compiler (g++) 
lucid
the one used by the Lucid compiler (lcc) 
arm
the one specified by the C++ Annotated Reference Manual 
hp
the one used by the HP compiler (aCC) 
edg
the one used by the EDG compiler 
gnu-v3
the one used by the GNU C++ compiler (g++) with the V3 ABI. 
java
the one used by the GNU Java compiler (gcj) 
gnat
the one used by the GNU Ada compiler (GNAT).

--help
Print a summary of the options to c++filt and exit. 
--version
Print the version number of c++filt and exit.

Warning: c++filt is a new utility, and the details of its user interface are subject to change in future releases. In particular, a command-line option may be required in the the future to decode a name passed as an argument
on the command line; in other words,

          c++filt symbol
          

may in a future release become

          c++filt option symbol
          

Footnotes

  1. MS-DOS does not allow + characters in file names, so on MS-DOS this program is named cxxfilt.

RHEL5和RHEL6中的sctp_event_subscribe定义大不同

近来碰到一个关于SCTP的问题:某个产品跑在Monta Vista上,其内核版本号为2.6.21;可每次该产品泡在我们的Red Hat Enterprise Linux 5.5上时,都会报错错误信息如下:

^?0 2011-08-16 09:11:57.316267 coolnjmcl018 AMMServ 26555[26566] ../com/AMMSSctpLib.cc,369 [EAMMS1315] AMMSSctpLib::ammsSetSockOpt() setsockopt - Invalid argument
^?1 2011-08-16 09:11:57.316326 coolnjmcl018 AMMServ 26555[26566] ../com/AMMSAccessServer.cc,779 [EAMMS1036] AMMSAccessServer::setSocketOpts(): failed to set SCTP_EVENTS for socket 6

ammsSetSockOpt()调用了Linux API setsockopt()。产品的同事告诉我们他们升级过libsctp.so,于是我们copy了MV中的这个shared lib到RHEL中,问题依旧。后来我们以为是RHEL5.5的内核和Monta Vista的内核不一致,于是我把RHEL的内核从2.6.18-194.el5升级到2.6.18-238.9.1.el5,问题还在。当我们还在考虑要不要把我们的server替换为Monta Vista时,一位同事受http://centos.org/modules/newbb/viewtopic.php?viewmode=threaded&order=ASC&topic_id=18994&forum=37&move=next&topic_time=1236769500
的启发,把setsockopt()最后一个参数由sizeof(events)改为8,竟然成功了! events定义如下。

struct sctp_event_subscribe events; 


最终,发现RHEL5和RHEL6中struct sctp_event_subscribe的定义竟然完全不同!要想根本解决上面的问题,只能升级操作系统到RHEL6了。

RHEL5中的定义:http://rhkernel.org/RHEL5+2.6.18-194.el5/include/net/sctp/user.h#L367

/*
 364 * Described in Section 7.3
 365 *   Ancillary Data and Notification Interest Options
 366 */
 367struct sctp_event_subscribe {
 368        __u8 sctp_data_io_event;
 369        __u8 sctp_association_event;
 370        __u8 sctp_address_event;
 371        __u8 sctp_send_failure_event;
 372        __u8 sctp_peer_error_event;
 373        __u8 sctp_shutdown_event;
 374        __u8 sctp_partial_delivery_event;
 375        __u8 sctp_adaption_layer_event;
 376};

RHEL 6中的定义:http://rhkernel.org/RHEL6+2.6.32-71.18.2.el6/include/net/sctp/user.h#L406

/*
 403 * Described in Section 7.3
 404 *   Ancillary Data and Notification Interest Options
 405 */
 406struct sctp_event_subscribe {
 407        __u8 sctp_data_io_event;
 408        __u8 sctp_association_event;
 409        __u8 sctp_address_event;
 410        __u8 sctp_send_failure_event;
 411        __u8 sctp_peer_error_event;
 412        __u8 sctp_shutdown_event;
 413        __u8 sctp_partial_delivery_event;
 414        __u8 sctp_adaptation_layer_event;
 415        __u8 sctp_authentication_event;
 416};
 417

Displacement Activity

你是否有过这样的经历:眼看考试或某个任务、活动的大限将至,自己很是担心,可你却不是在努力准备,而是看电影、玩游戏或者和朋友聊天? 至少对于我,这样的矛盾行为并不罕见。今天才知道,这种行为叫做Displacement Activity,是人和动物身上的一种普遍存在的行为。

Displacement Activity貌似还没有确切的中文翻译,有在线词典译作“替换行为”,个人认为翻译不准确,不予采纳。根据我的理解,Displacement Activity就是当你不得不去做某件事情的时候,你担心会失败于是产生一种不去做的消极心态,当你无法做出一个做还是不做的决定时,纠结中你下意识得选择逃避——不由自主的做一些让自己感觉舒服(但很明显不在状态)的事情,比如吃饭、看电影、睡觉、玩游戏、逛街等等。恰恰由于你的逃避,往往会使事情办的更糟,所以等到下一个你不得不面对的抉择时,你的这种表现会更严重,由此造成恶性的循环往复……

个人感觉Displacement Activity还是心理不够强大的表现。真的强者不会有这种表现的。悲哀的是这种状态已伴随我十几年,至少在高中时就有这种表现,目前看来已经越来越严重了。我能想到的解决这种现象的根本方法就是:1. 深入研究你要做的事情,搞清楚你要做什么,想清楚怎么做,多看一些别人成功的经验(以及别人失败的教训,当然这种东西比较少了);2. 制定一个达到目标所需要的可行的计划;3. 每天坚持执行你的计划;4.
尽量不要调整你的计划。这只是一个设想,目前本人还没有真正实践过。

下面是搜集的相关解释。

Displacement Activities are behaviors that animals(including human beings) have conflicting drives. Such behaviors are completely out of place.

Displacement behavior is usually thought of as self-grooming, touching, or scratching, which is displayed when an animal has a conflict between two drives, such as the desire to approach an object, while
at the same time being fearful of that object. 
With the fall of drive theory into disfavor, animal behaviorists paid little attention to displacement behavior until Maestripieri et al. (1992) pointed out that displacement behavior might be a good
measure of anxiety levels.

------------------------------

From Wiki: http://en.wikipedia.org/wiki/Displacement_activity

A displacement activity is the result of two contradicting instincts in a particular situation. Birds, for example, may peck at grass when uncertain whether to attack or flee from an opponent;
similarly, a human may scratch his or her head when they do not know which of two options to choose.

Displacement activities often involve actions to bring comfort such as scratching, drinking or feeding.

The first description of a displacement activity (though not the use of the term) is probably by Julian Huxley in 1914. The subsequent development of research on displacement activities was a direct consequence
of Konrad Lorenz's works on instincts. However, the first mentions of the phenomenon came in 1940 by the two Dutch researchers Nikolaas Tinbergen and Adriaan Kortlandt.

---------------------------

From http://c2.com/cgi/wiki?DisplacementActivity

Activity undertaken when some more important task's deadline is looming.

When I was studying for my final degree examinations I played more bridge than ever before. That was pretty much a pure DisplacementActivity.

I'm wondering how much other authors and programmers suffer from this weakness -- SteveHolden

----------------------------

From http://baillement.com/displacement-delius.html

In 1940 Tinbergen and Kortlandt independently drew attention to a behavioural phenomenon which has since been called displacement activity and has received a good deal of attention. Although no binding rules exist
by which displacement behaviour can be recognized, the term is applied to behaviour patterns which appear to be out of context with the behaviour which closely precedes or follows them either in the sense that they do not seem functionally integrated with
the preceding or following behaviour or that they occur in situations in which causal factors usually responsible for them appear to be absent or at least weak compared with those determining the behavioural envelope.

Displacement activities occur in three situations: motivational, conflict, frustration of consummatory acts and physical thwarting of performance. Several theories have been put forward to explain
the causal mechanism involved. A variety of behaviour patterns have been reported as displacement activities, even in a single species, but this variety needs revision.

Monographie treatments of the behaviour of any one species usually indicate only two or three activities which according te the judgment of the observer occur commonly as displacement. None of the theories on displacement
activities gives cogent reasons why particular behaviour patterns should be more common than others as displacement activities, apart from stating that the causal agents which usually elicit them in non-displacement situations can also be presumed te be present,
if only weakly, in the displacement context, or remarking that those patterns are prepotent in the repertoire of the animal.

Immaneul Kant's Philosophy of Morality

Following are part of my notes of the famous Harvard open course Justice. Kant's theory is too hard to be understood in a shot time. I think the best way is to record his main idea and try to digest in the future.

===============================================================================================

Part 1  Kant's Conception of Freedom

Kant thinks that the individual person, all human beings, have a certain dignity that commands our respect.

The reason the individual is sacred or the bearer of rights, doesn't stem from the idea that we own ourselves, but instead from the we are all rational beings, which means we are beings who are capable of reason.

We are also autonomous beings, which is to say that we are beings capable of acting and choosing freely.

The capacity of reason and freedom, isn't the only capacity we have. It is our rational capacity that makes our distinctive.

Freedom is the opposite of necessity.

Kant's Conception of Freedom
Autonomy:
To act freely (= to act autonomously =)
To act according to a law I give myself
Heteronomy:
To act according to desires I haven't chosen myself

To act freely is not to choose the best means to a given end; it's choose the end itself for its own sake. In so far we act on inclination or pursue pleasure, we act as means to the realization of ends given outside of us. We are instruments rather than  authors of the purposes we pursue, that's the heteronymous determination of the will.
On the other hand, in so fas as we act autonomously, according to a law we give ourselves, we do something for its own sake as an end in itself. When we act autonomously, wee seems to be instruments to purposes given outside us, we become as ends in ourselves. This capacity to act freely, is what gives human life its special dignity.
Respecting human dignity means regarding persons not just as means, but also as ends in themselves. This is why it is wrong to use people for the sake of other people's well-being or happiness. This is the real reason that utilitarianism goes wrong.

------------------------------------
Part 2. Kant's Conception of Morality

Kant's Conception of Morality
*moral worth of an action depends on motive (do the right thing for the right reason, or for the sake of duty)

What makes an action morally worthy, consists not in the consequences or in the results that flow from it, what makes an action morally worthy has to do with the motive, with the quality of the will, with the Intention for which the act is done. What matters is the motive, and the motive must be of a certain kind.

A good will isn't good because of what it effects or accomplishes, it's good in itself. Even if by utmost effort the good will accomplishes nothing it would still shine like a jewel for it's own sake as something which has it's full value in itself. -- Immanuel Kant
The idea is that the motive confers the moral worth on an action and the only kind of motive that can confer moral worth on an action is the motive of duty.
The opposite of acting out of duty, is all of the motives having to do with our inclinations. Inclinations refer to all of our desires, all of our contingently given wants, preferences, impulses, and the like.
Only actions done for the sake of the moral law, for the sake of duty, only these actions have moral duty.

-------------------------------
Part 3. Kant's Conception of Supreme Morality

What's the supreme principle of morality?
Only one kind of motive is consistent with morality, the motive of duty, doing the right thing for the right reason. Other motives are summed up by Kant in the category of inclination.
Every thine the motive for what we do is to satisfy a desire or a preference that we may have, to pursue some interest, we are acting of inclination.
It's fine to have sentiments and feelings that support the right thing provided they don't provide the reason for acting. One may have more than one motive, but it doesn't mean that the action is devoid of moral worth, just because he has one other motive -- the motive which involves duty is what gives the moral worth.

Kant's Three Contrasts:
(MORALITY) Motives:                         Duty vs. Inclination
(FREEDOM)  Determination of will :   autonomous  vs. Heteronomous
(REASON) Imperatives:                      Categorical vs. Hypothetical

If reason determines my will, then the will becomes a power to choose indecent of the dictates of nature, or inclination or circumstance. So, connected with Kant's demanding notions of morality and freedom, is a specially demanding notion of reason.

How can reason determine the will?
There are two ways. There are two different commands of reason. One is an imperative. An imperative is an *ought*.
One kind of imperative, perhaps the most familiar kind, is a *hypothetical* imperative. Hypothetical imperatives use instrumental reason. If want X then do y. It's means-ends reason.
If the action would be good solely as a means to something else, the imperative is hypothetical; if the action is represented as good in itself and therefore as necessary... for a will which of itself accords with reason, then the imperative is *categorical*.

What is the categorical imperative? What is the supreme principle of morality? What does it command of us?
THE CATEGORICAL IMPERATIVE
(1) The Formula of Universal Law
Act only on that maxim whereby you can at the same time will that is should become a universal law. "the maxim", he means a rule that explains the reason for what you are doing, a principle. For example, promise keeping.
And the test, the way we can determine that the false promise is at odds with the categorical imperative, is try to universalize it, universalize the maxim upon which you are about to act. If the maxim universalized would undermine itself, then it's not categorical.

(2) The Formula of Humanity as End
We can't base the categorical imperative on any particular interests, purposes, or ends, because then it would be only relative to the person whose ends they were. But suppose, however, there were something whose existence has in itself an absolute value.... an end in itself.... then in it, and in it alone, would there be the ground of a possible categorical imperative.
"I say that man, and in general every rational being, exists as an end in himself, not merely as a means for arbitrary used by this or that will." -- Kant

Act in such a way that you always treat humanity, whether in your own person or in the person of any other, never simply as a means, but always at the same time, as an end.

Respect is respect for humanity which is universal, for a rational capacity which is universal, and that's why violating it, in my own case, is as objectionable as violating it in the case of any other.

-------------------------------
Part 4. The Application of Kant' Categorical Imperative on Lying

How is a categorical imperative possible? How is morality possible?

"when we think of ourselves as free, we transfer ourselves into the intelligible world as members and recognize the autonomy of the will." --immanuel Kant
Only because the idea of freedom makes me a member of an intelligible world, the categorical imperative is possible.

Since we inhabits simultaneously the two standpoints, the two realms, the realm of freedom and the realm of necessity, there is always potentially a gap between what we do and what we ought to to, between is and ought.
Morality is not empirical. Whatever you see in the world, whatever you discover through science, can't decide moral questions. Morality stands at a certain distance from the world, from the empirical world. That's why no science could deliver moral truth.

From Kant's point of view, there actually is a world of difference between a lie and a misleading truth.

White lie 善意的谎言
Kant preferred leading truth(误导的真相) to a white lie.
Unlike a falsehood, unlike a lie, a misleading truth pays a certain homage to duty.

-----------------------------------
Part 5  The Application of Kant's Categorical Imperative On Contract

Just laws arise from a certain kind of social contract, which is of an exceptional nature. What makes the contract exceptional is that it is not an actual contract, that happens when people come together and try to figure out what the constitution should be. That the contract generates justice is an idea of reason.

A contract that generates principles of right is merely an idea of reason, but it has undoubted practical reality, because it can oblige every legislator to frame his laws in such a way that they could have been produced by the united will of the whole nation.

"Each person possesses an inviolability founded on justice that even the welfare of society as a whole cannot override... The rights secured by justice are not subject to political bargaining or to the calculus of social interests." -- John Rawls

Moral Force of Actual Contracts
1. How do they bind or obligate?
(1) consent-based -> AUTONOMY(自律)
(2) benefit- based -> RECIPROCITY(互惠) : contracts sometimes bind us in so far as they are instruments of mutual benefit.

2. How do they justify the terms they produce?
Actual contracts are not self-sufficient moral instruments of any actual contract or agreement. The fact of the agreement never guarantees the fairness of the agreement.

选中Excel单元格自动导入多个Excel worksheets

前日完成将多个Excel文件批量导入某个Excel文件中老婆规定的任务后,老婆又提出了新的要求:

  1. 可以update每个worksheet
  2. 对导入的worksheets进行排序
  3. 自动匹配代导入文件的文件名
  4. 将导入的worksheets中的特定多个单元格(cells)的内容自动填充到某一表格的特定区域

本文中用到的Excel文件及VBA宏可以在此处下载。

表1  选中的单元格
1 工作表 1
2 工作表 2
3 工作表 3
4 工作表 4
5 工作表 5
6 工作表 6
7 工作表 7
8 工作表 8
9 工作表 9
10 工作表 10

对应的各个worksheet的名字(Name)是:01 工作表 1, 02 工作表 2,03 工作表 3,……,10 工作表 10.


待导入的Excel文件的名字为“02 某某银行XX项目_工作表 1_20110701.xls”。

Update 2011-07-13 21:50

应老婆的要求,更新了程序,遇到并解决的问题有:

  1. Office 2003和2007不兼容——有些method在office2003中正常工作但在office2007中却不再支持,如判定某文件是否存在的函数,解决方法参见FindFileName函数。
  2. 如果某个表中的一些单元格被筛选,则会遇到“不能复制合并的单元格”(Can't copy merged cell)的问题,解决方法就是在copy前强制关闭autofilter:   newWB.Sheets(SheetToBeCopy).AutoFilterMode = False ' disable auto filter
  3. 关闭打开的Excel文件或者copy单元格时会有各种各样的对话框弹出来,解决办法就是加上下面语句:

Application.DisplayAlerts = True
newWB.Close SaveChanges:=False  ' close without change
Application.DisplayAlerts = True

Update 2011-07-14 15:37

傻瓜型用户的需求就是无穷无尽啊……我老婆发现在选择不连续的区域时,只有第一个区域会被处理,其他的没有变化。顶着挨骂的压力Google之后才知道,原来Slection.Areas可以包含所有不连续的选择,然后通过遍历,处理所有的选择……程序改动如下。

       ' Create new worksheets
        ' Discontinuous selection is supported by Selection.Areas
        For Each Rng In Selection.Areas
            Set SelRange = Rng.Cells
            Set ColNo = Rng.Columns(1)
            Set ColDepart = Rng.Columns(2)
            idx = 1
            For Each cell In ColDepart.Cells
                no_str = ColNo.Cells(idx).Value
                If Len(no_str) = 1 Then
                    no_str = "0" + no_str
                End If
                Call CreateNewWorksheet(no_str, cell.Value, myFolder, SheetToBeCopy) ' call is needed here
                idx = idx + 1
            Next
        Next

实现以上所有需求的代码如下(Update 2011-07-14 15:37):

<span style="font-family: 'Times New Roman';font-size:16px; "></span><pre style="word-wrap: break-word; white-space: pre-wrap; ">                                         
Option Explicit
Dim curWS As Worksheet


            
          

Importing Multi-Excel Files/Worksheets Into An Excel Workbook

Two days ago, my wife asked me to write an Excel VBA script to automatically import multi-Excel worksheets stored in different workbooks into an already opened Excel workbook.  Her requirements were:

  1. Select a range in a worksheet, which stores the names of worksheets to be imported. After executing the macro, worksheets will be created if it doesn't exist, or it will be updated according to the specified  Excel worksheet in another Excel workbook. Table 1 is the range selected in the worksheet, in which the first column is the serial number of worksheet, the second column denotes department name and the worksheet name should be like "01 Department A".
  2. The imported/created worksheets should be sorted by the serial number of Table 1.
  3. The macro should be smart enough to match the Excel files to be imported. The name is like "01 XXXX_Department  A_20110707.xls".
  4. After importing, specified cells in every other worksheets should be automatically copied to cells on the same row next to department.

Table 1  Selected Range of a worksheet

1 Department  A
2 Department  B
3 Department  C
4 Department  D
5 Department  E
6 Department  F
7 Department  G
8 Department  H
9 Department  I
10 Department  J

Actually I am not familiar with VBA, although I studied Visual Basic 6.0 for several months, I rarely touched it after passing the Jiangsu Province Computer Rank Test Level 2 in 2003. Besides, almost all my work was done in Linux/UNIX last 3 years.  As a result, I have to Google every VBA syntax and tips all day long.

Finally, I finishes the VBA macros and meet my wife's requirement in a inelegant way. Following is the verbose source code.

Following the macro to implement first 3 requirements.
[sourcecode language="vb"]
Option Explicit
Dim curWS As Worksheet

Sub LoadWorksheets()
'
' LoadWorksheets Macro
' Macro recorded 7/13/2011 by Bo Yang
'
' Keyboard Shortcut: Ctrl+Shift+L
'
' *How to use this macro?*
' *Select columns "??(NO)" and "??(Deparment)" and then run this macro.*
'
Application.ScreenUpdating = False ' stop screen flickering

' Create new sheets according to selected cells and copy the
' contebts of other files into the new sheets
Dim YesNo As Variant, myFolder As String, MyLF As String
Dim SelRange As Range, ColNo As Range, ColDepart As Range, cell As Range, Rng As Range
Dim SheetName As String, SheetToBeCopy As String
Dim ColCnt As Integer
Dim no_str As String, idx As Integer

myFolder = "D:\" '*****Change this value as you need*****
SheetToBeCopy = "信息资产风险评估" ' *****Change this value as you need*****

MyLF = Chr(10) &amp; Chr(13) ' a line feed command
Set curWS = ThisWorkbook.ActiveSheet ' Save current worksheet

' check that if user select valid columns
ColCnt = Selection.Columns.Count

If ColCnt 2 Then
MsgBox ("Please select 2 columns!!!" &amp; MyLF &amp; _
"The first column must be digital numbers," &amp; MyLF &amp; _
"And the Second column must be department names" _
)
Exit Sub
End If

YesNo = MsgBox("This Macro is going to create new worksheets according to your selected cells." &amp; MyLF &amp; _
"Do you want to continue?", _
vbYesNo, "Caution")
Select Case YesNo
Case vbYes
myFolder = InputBox("Please enter the folder where all your Excel files locates:", Default:=myFolder)
SheetToBeCopy = InputBox("Please enter the worksheet you want to copy:", Default:=SheetToBeCopy)

' Create new worksheets
' Discontinuous selection is supported by Selection.Areas
For Each Rng In Selection.Areas
Set SelRange = Rng.Cells
Set ColNo = Rng.Columns(1)
Set ColDepart = Rng.Columns(2)
idx = 1
For Each cell In ColDepart.Cells
no_str = ColNo.Cells(idx).Value
If Len(no_str) = 1 Then
no_str = "0" + no_str
End If
Call CreateNewWorksheet(no_str, cell.Value, myFolder, SheetToBeCopy) ' call is needed here
idx = idx + 1
Next
Next

curWS.Activate

' Sort worksheets
Call SortWorksheets

Case vbNo
Application.ScreenUpdating = True
Exit Sub
End Select

curWS.Activate
Application.ScreenUpdating = True
End Sub

Function CreateNewWorksheet(no As String, Depart As String, FolderName As String, SheetToBeCopy As String) As String
Dim oSheet As Worksheet, vRet As Variant
Dim SheetName As String, FileName As String
Dim Entry As Integer, i As Integer

' Determine where to insert new worksheet
Entry = 0
For i = Sheets.Count To 1 Step -1
If Val(Worksheets(i).Name) &gt; 0 Then
Entry = i
GoTo Determ_Entry
End If
Next i
Determ_Entry:
If Entry = 0 Then
Entry = Sheets.Count
End If

'Example of one worksheet name:
' 07 oa祙?DDISMS?ㄩ????_D???钻2???_D?'?轶???_20110705.xls
SheetName = no + " " + Depart
If Not SheetExists(SheetName) Then
'worksheet XXX doesn't exist in current workbook
'creating a new excel worksheet

Set oSheet = Worksheets.Add
With oSheet
.Name = SheetName
.Move After:=Sheets(Entry)
.Activate
End With
End If

FileName = FindFileName(no, Depart, FolderName)
If FileName "" Then
Call CopyWorksheet(SheetName, FileName, SheetToBeCopy)
End If

Exit Function

End Function

Function SheetExists(SheetName As String) As Boolean
' returns TRUE if the sheet exists in the active workbook
SheetExists = False
On Error GoTo NoSuchSheet
If Len(Sheets(SheetName).Name) &gt; 0 Then
SheetExists = True
Exit Function
End If
NoSuchSheet:
End Function

Function CopyWorksheet(SheetName As String, FileName As String, SheetToBeCopy As String) As String
'open Excel files and copy the contents to this sheet
Dim newWB As Workbook, curWB As Workbook
Dim startRange As Range

If Dir(FileName) "" Then
' file exists
' Clear all cells of current worksheet
Sheets(SheetName).UsedRange.Clear
Application.DisplayAlerts = False ' disable alerts

' Open workbooks to be copied
Set curWB = ThisWorkbook ' For WorkBook and Range objects, set is necessary during assignment
Set newWB = Workbooks.Open(FileName)
newWB.Sheets(SheetToBeCopy).AutoFilterMode = False ' disable auto filter
Set startRange = newWB.Sheets(SheetToBeCopy).UsedRange ' Only used range will be copied
newWB.Sheets(SheetToBeCopy).UsedRange.Copy
' paste to target worksheet
curWB.Activate
Sheets(SheetName).Range(startRange.Address).PasteSpecial
Application.CutCopyMode = False 'Clear Clipboard
newWB.Close SaveChanges:=False ' close without change
Application.DisplayAlerts = True

End If

End Function

Function FindFileName(no As String, Depart As String, FolderName As String) As String
Dim Coll_Docs As New Collection
Dim Search_path, Search_Filter, Search_Fullname As String
Dim DocName As String
Dim i As Long

Search_path = FolderName ' where ?
Search_Filter = no + "*" + Depart + "*" + ".xls" ' what ?
Set Coll_Docs = Nothing

DocName = Dir(Search_path &amp; "\" &amp; Search_Filter)

Do Until DocName = "" ' build the collection
Coll_Docs.Add Item:=DocName
DocName = Dir
Loop

If Coll_Docs.Count = 1 Then
FindFileName = Search_path &amp; "\" &amp; Coll_Docs(1)
Else
FindFileName = ""
End If

End Function

Function SortWorksheetsByName() As String
' sort worksheets in a workbook in ascending order
Dim sCount As Integer, i As Integer, j As Integer

Application.ScreenUpdating = False
sCount = Worksheets.Count
If sCount = 1 Then Exit Function
For i = 1 To sCount - 1
For j = i + 1 To sCount
If Worksheets(j).Name 0 Then
Entry = i
GoTo Determ_Entry
End If
Next i
Determ_Entry:

For i = Entry To cnt - 1
For j = i + 1 To cnt
If Val(Worksheets(i).Name) &gt; Val(Worksheets(j).Name) Then
Worksheets(j).Move Before:=Worksheets(i)
End If
Next j
Next i

curWS.Activate
'Application.ScreenUpdating = True
End Function
[/sourcecode]

And here comes the macro to implement the 4th requirement.
[sourcecode language="vb"]
Option Explicit

Sub UpdateCells()
'
' UpdateCells Macro
' Macro recorded 7/13/2011 by Bo Yang
'
' Keyboard Shortcut: Ctrl+Shift+C
'
' Risk:Cell
' 5: L2 , 4: L3 , 3: L4 , 2: L5 , 1: L6
Dim Risk5 As Range
Dim num As String, depart As Range, idx As Integer
Dim SheetName As String
Dim SelRange As Range
Dim curWS As Worksheet

Application.ScreenUpdating = False

Set curWS = ActiveSheet
Set SelRange = Selection

idx = 1
For Each depart In SelRange.Columns(2).Cells
num = SelRange.Columns(1).Cells(idx).value
If Len(num) = 1 Then
num = "0" + num
End If
SheetName = num + " " + depart.value

Set Risk5 = SelRange.Columns(3).Cells(idx)

ThisWorkbook.Sheets(SheetName).Range("L2:L6").Copy
Risk5.Select
Risk5.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=True
Application.CutCopyMode = False 'Clear Clipboard

idx = idx + 1
Next

Application.ScreenUpdating = True
End Sub
[/sourcecode]

将多个Excel文件批量导入某个Excel文件中

这是我老婆提出的一个需求:(1)选中Excel表格中的某些行或列,运行某个Macro,自动根据选中的cells创建新的worksheets,worksheets的名字就是选中的cells的名字。(2)创建新的worksheet的同时,要把某指定目录下与新的worksheet同名的Excel文件的内容copy到新的worksheet中去。

下面是搜索了半天之后搞出来的Macro,没有异常处理,而且使用了copy/paste,文件太多时效率肯定不高。其实完全可以参照

Copy a sheet from each workbook into your workbook in a folder using VBA in Microsoft Excel 和 Optimize Slow VBA Code 中的方法来优化。

Sub LoadSheets()
    Application.ScreenUpdating = False  ' stop screen flickering
    
    ' Create new sheets according to selected cells and copy the
    ' contebts of other files into the new sheets
    Dim YesNo As Variant, myFolder As String, MyLF As String
        
    MyLF = Chr(10) & Chr(13)    ' a line feed command
    myFolder = "D:Documents and SettingsbonnyMy Documentstools"   'change this to the location of saved XML files
    'Windows 7下C盘默认不可写,请修改DefFolder的值
    
    YesNo = MsgBox("This Macro is going to create new worksheets according to your selected cells." & myclf & _
        "Do you want to continue?", _
        vbYesNo, "Caution")
    Select Case YesNo
    Case vbYes
        myFolder = InputBox("Please enter the folder where all your Excel files locates", Default:=myFolder)
        'Create new worksheets
        For Each cell In Selection.Cells
            Call CreateNewWorksheet(cell.Value, myFolder)
        Next
    Case vbNo
        Exit Sub
    End Select
    
    Application.ScreenUpdating = True
End Sub


            
          

Solaris下/usr/lib/secure/0@0.so.1的错误

 

这两天一直被下面的错误所困扰:

AP13: lb -m ccmscell uptime 
ld.so.1: uname: fatal: /usr/lib/secure/0@0.so.1: open failed: No such file or directory
ksh[216]: 4412 Killed
ld.so.1: uptime: fatal: /usr/lib/secure/0@0.so.1: open failed: No such file or directory

  

lb是一个调用rsh的脚本,ccmscell是一个server pool,uname是在lb中被调用的。

 

仔细研究了N遍相关的脚本,Google了N次相关的错误信息,都没有找到有价值的线索。后来问了一位做过IT的同事,她说以前遇见过类似的问题,可她的解决方案最终被证明无效。

 

最终发现不是所有的server上执行这条命令都有问题,有些是可以执行的。对比了之后发现,如果/usr/lib/secure/0@0.so.1的group设置为bin,owner设为root,就不会出现上面的问题。出问题的server上/usr/lib/secure/0@0.so.1的group为other。

 

进一步调查后发现,/usr/lib/secure/0@0.so.1是在Solaris 5.8上被设为LD_PRELOAD_32的,因为很多程序要被setuid+chroot的伪root调用。当且仅当上面的命令被该伪root执行时,才会出现上面的错误!

 

幸亏Solaris 5.8已经开始走进坟墓了,即使在落后如我们公司的地方!

 

【update2011-06-23】:

今天发现root cause 不是由于/usr/lib/secure/0@0.so.1的group不对,而是因为remote server(比如pool ccmscell中的server)上没有/usr/lib/secure/0@0.so.1 —— 执行rsh命令的login是setuid+chroot实现的伪root,因此远程的server就需要/usr/lib/secure/0@0.so.1了。

【update 2012-03-12】

今天在Solaris 9上遇到了这样一个错误:

    ld.so.1: pt_chmod: warning: /lib/0@0.so.1: open failed: illegal insecure pathname

查了很久才想起来有可能是/usr/lib/secure/0@0.so.1造成的。一检查/usr/lib/secure/0@0.so.1,果然不存在。

在一个正常工作的server上,

AP31: echo $LD_PRELOAD_32
/usr/lib/secure/0@0.so.1

在不能工作的server上,

AP13: echo $LD_PRELOAD_32
/lib/0@0.so.1

——仅仅升级了一个软件就又把这个library搞丢了,某些同志们啊,唉……