Windows Server 2003 启动过程中常见错误的解决方案
摘要:在Windows Server 2003启动过程中,会出现各种各样的问题,本文介绍了操作系统启动过程的几个阶段,收集了一些经常出现的错误,并结合 Windows 操作系统启动过程,针对这些错误提出了解决方法。
当诊断一个系统启动错误时,判断系统是在哪一阶段出现错误非常关键,系统启动过程根据 CPU 架构不同略微有些差异,下面我们简单介绍一下 x86-based 系统启动过程的几个阶段:
1. Pre-Boot Sequence
2. Boot Sequence
3. Kernel Load Sequence
4. Kernel Initialization Sequence
5. Logon Sequence
6. Plug and Play detection
阶段 1: Pre-Boot Sequence
在计算机加电后开始准备启动操作系统之前,有一个 Pre-Boot Sequence 的过程,主要是计算机的 BIOS 中配置的设备引导顺序寻找启动设备,Pre-Boot Sequence 可以分下以下步骤:
(1)系统加电自检:主要监测主板、CPU,内存及其他计算机所使用的硬件设备的信息;
(2)找到合适的启动设备并加载MBR,MBR中有分区表和主引导代码,通过主引导代码定位到活动分区;
(3)通过 MBR 找到活动分区后,从活动分区中加载 BOOT SECTOR 到内存并执行其中的代码;
(4)通过 BOOT SECTOR 找到 NTLDR 文件,加载 NTLDR 到内存中并执行;
可能出现的问题及解决方法:
(1)MBR 损坏
现象 - 分区表不正确
现象 - 主引导代码损坏
现象 - NTDETECT.COM 搜集硬件信息失败
原因:
由于病毒或者其他人为的误编辑导致引导硬盘的 MBR 损害;
解决方法:
利用Windows PE系统引导计算机后,使用 WinHex 工具对引导磁盘的 MBR 进行修复操作;
(2)硬件配置不正确
现象:主板报错;
原因:关键的硬件损害或者配置不正确,如内存条损坏;
解决方法:要通过进一步硬件故障检测,针对不同硬件故障做不同处理;
(3)找不到活动分区
现象:按照设备启动顺序遍历后,最后停在如下界面:
原因:可能是通过 fdisk 工具编辑磁盘分区表后没有指定活动分区;
解决方法:利用Windows PE系统引导计算机后,使用 WinHex 工具对引导磁盘的 MBR 的分区表进行编辑,指定正确的分区表条目的属性为活动分区,然后重新引导操作系统;
(4)NTLDR 文件缺失或损坏
现象:如下图所示,输出错误信息“NTLDR is missing”;
原因:NTLDR 文件被病毒删除或损害,或者文件系统损坏,导致了 NTLDR 文件的损坏;
解决方法:可以通过系统恢复或者 Windows Server 2003 引导盘 NTLDR 文件;
(2)BIOS 配置不正确
现象:
原因:
解决方法:根据实际情况调整 BIOS 配置;
阶段 2: Boot Sequence
当 Pre-Boot Sequence 的阶段完成后,开始进入 Boot Sequence 阶段。可以分下以下步骤:
(1)NTLDR 将 CPU 工作模式从 Real-Mode 切换至 Protected-Mode,然后启动文件系统驱动用于 支持计算机上的文件系统;
(2)NTLDR 读取 BOOT.INI 文件内容,用于创建初始化引导选项,如果选择的是 Windows Server 2003, Windows NT 之外的操作系统,BOOTSECT.DOS 文件被读入内存,用于加载其他的操作系统,Windows Server 2003 引导过程中断;
(3)当系统初始化引导选项被选中后,根据该引导项对应的磁盘号和分区号定位启动卷;
(4)从启动卷中找到 NTDETECT.COM 文件,NTDETECT.COM 检测系统基本的硬件配置信息并且把配置信息写入注册表中的 HKEY_LOCAL_MACHINE 键,NTDETECT.COM 识别的硬件包括并不仅限于 串口、并口、键盘、鼠标、软盘、SCSI 适配器 和 显卡;
(5)将控制权交给 NTOSKRNL.EXE,进入下一阶段;
可能出现的问题及解决方法:
(1)启动文件缺失或损坏
现象:
原因:NTLDR,BOOT.INI,BOOTSECT.DOC,NTDETECT.COM 或 NTOSKRNL.EXE中的一个缺失或损坏,导致操作系统无法正常启动,一般情况下,通过错误信息能准确的判断是那个文件缺失或损坏;
解决方法:可以通过系统恢复自动修复;
(2)BOOT.INI 配置不正确
现象:
原因:人为误编辑 BOOT.INI 文件或者修改了磁盘配置;
解决方法:利用Windows PE系统引导计算机后,检查 BOOT.INI 文件内容,并根据实际情况重新配置;
(3)硬件无法识别或者配置不正确
现象:界面错误信息指向 NTDETECT.COM
原因:
解决方法:需要进一步排查具体原因,可以通过逐个移除新加硬件和相应驱动程序来定位;
关于此阶段中一些重要的启动文件说明:
BOOT.INI
用于在系统启动过程中创建系统选择菜单,每个系统项在文件中都有对应的条目与之对应,记录了该系统的启动分区。BOOT.INI 文件一般为位于根目录,具有系统属性和隐藏属性。
BOOTSECT.DOS
一个选项配置文件,在部署了多操作系统的环境中,如果选择引导的是 Windows Server 2003, Windows NT 之外的操作系统,这个文件会被加载。BOOTSECT.DOS 文件位于根目录下,具有系统属性和隐藏属性。
NTDETECT.COM
用于检测操作系统已经安装的硬件设备,并且将这些硬件设备的信息添加到注册表。NTDETECT.COM 文件位于系统分区的根目录下,具有系统属性、隐藏属性和只读属性。
NTOSKRNL.EXE
用于加载 Windows Server 2003 操作系统,NTOSKRNL.EXE 文件位于 %windir%/system32。
阶段 3: Kernel Load Sequence
当 Boot Sequence 的阶段完成后,NTDETECT.COM 搜集的所有信息都传递给了 NTOSKRNL.EXE,Kernel Load Sequence 可以分下以下步骤:
(1)NTOSKRNL.EXE 加载并初始化;
(2)初始化执行子系统,启动类型为 System-Start 的设备驱动程序;
备注:这里说的执行子系统,是指 Process And Thread Manager、Virtual Memory Manager、I/O Manager、Object Manager、Runtime Libraries 以及其他需要工作在内核态的服务。
(3)为运行原生应用程序准备系统环境;
备注:这里说的原生应用程序,需要解释一下,Windows 操作系统提供两种类型的 API,一种是我们通常所说的 Windows API,所有的 Windows 程序都需要依赖 Windows API,另一种是 Native API,一些 Windows 组件如内核驱动程序 和 系统进程(如csrss.exe)依赖 Native API 。
(4)运行 SMSS.EXE
关于此阶段中一些重要的启动文件说明:
NTOSKRNL.EXE 在这一阶段的作用非常关键,它主要用于完成以下功能:
(1)加载 HAL.DLL (Hardware Abstraction Layer,是一个 Kernel-Mode 库),用于提供低级别的硬件交互接口,Windows 组件和第三方的设备驱动程序依赖 HAL 与底层硬件设备通信;
(2)加载操作系统Control Set,Control Set 用于控制系统配置信息(如列出需要被加载的设备驱动程序);
(3)加载低级别的设备驱动程序(如磁盘驱动程序 disk.sys);
可能出现的问题及解决方法:
现象:
原因:硬件设备驱动程序不匹配,或者安装了有 BUG 的安全、加密、过滤、第三方磁盘管理软件、存储管理软件;
解决方法:知道是做了什么变更后出现的就比较好解决,回退操作,也可以借组于系统的 “最后一次正确配置”的高级选项;
阶段 4: Kernel Initialization Sequence
Kernel Initialization Sequence 主要创建 HKEY_LOCAL_MACHINE\HARDWARE 注册表项,运行高优先级的子系统和服务,可以分下以下步骤:
(1)一旦 Kernel 成功加载后,会创建 HKEY_LOCAL_MACHINE\HARDWARE 注册表项,这个注册表项用于指定系统启动时的硬件设备的配置信息;
(2)初始化随 Kernel 加载的设备驱动程序;
(3)运行高优先级的子系统和服务;
备注:高优先级的子系统包括并不仅限于 POSIX Subsystem,OS/2 Subsystem。
可能出现的问题解决方法:知道是做了什么变更后出现的就比较好解决,回退操作,也可以借组于系统的 “最后一次正确配置”的高级选项;
阶段 5: Logon Sequence
smss.exe(Session Manager System)是 Logon Sequence 中的一个非常关键的角色,可以分下以下步骤:
(1)创建系统环境变量;
(2)启动 Win32 Subsystem 的 Kernel-Mode 部分(win32k.sys)和 User-Mode 部分(csrss.exe);
(3)启动在注册表项 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems 中列出的子系统;
(4)smss.exe 运行 winlogon.exe(Windows Logon Manager);
备注:附上对 winlogon.exe 程序功能的说明:
winlogon.exe is a system service that enables logging on and off of users. It is also responsible for loading user profile.
It invokes GINA( Graphical Identification and Authentication) which displays login prompt. The GINA accepts the user login credentials and passes it back to Winlogon.
Winlogon then Starts Lsass.exe (the Local Security Authority) and passes login credentials to LSA. LSA determine which user account databases is to be used for authentication eg: Local SAM or Active Directory in case you are in a windows domain.
(5)用户权限验证通过后, smss.exe 运行 Service.exe(Services Subsystem,SCM);
(6)Service.exe 遍历 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services,启动类型为“自动运行”的服务。
可能出现的问题及解决方法:
(1)登陆失败
现象:
原因:用户权限信息验证不通过;
解决方法:尝试找回权限信息,注意是否是域控导致,终极解决方案就是利用 PE 进入系统后用工具重置密码;
(2)服务启动失败
现象:
原因:原因太多,不一一枚举,cmd 输入 eventvwr.msc 打开 System Log 查看具体详情;
解决方法:根据 System Log 记录对症下药;
阶段 6: Plug and Play Device Detection
Plug And Play Device Detection 是一个系统自动检测新增 PnP 设备并为 PnP 设备自动查找驱动程序尝试使之能够正常功能的过程,可以分下以下步骤:
(1)检测启动过程中新增的设备,自动为设备分配系统资源;
(2)如果设备是 PnP 并且可以从对应的 Driver.cab 文件中找到对应的驱动程序,则提取驱动程序并自动安装;
可能出现的问题及解决方法:
PnP 设备无法正常工作
现象:
原因:驱动程序不匹配;
解决方法:找到匹配的驱动程序并安装;
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: Windows 系统自动登录编程
推荐阅读
-
Windows Server 2003 启动过程中常见错误的解决方案
-
ssh工作流程及原理-SSH(Secure Shell Protocol,安全的壳程序协议),它可以通过数据包加密技术将等待传输的数据包加密后再传输到网络上。ssh协议本身提供两个服务器功能:一个是类似telnet的远程连接使用shell的服务器;另一个就是类似ftp服务的sftp-server,提供更安全的ftp服务。 连接加密技术简介 目前常见的网络数据包加密技术通常是通过“非对称密钥系统”来处理的。主要通过两把不一样的公钥与私钥来进行加密与解密的过程。 公钥(public key):提供给远程主机进行数据加密的行为,所有人都可获得你的公钥来将数据加密。 私钥(private key):远程主机使用你的公钥加密的数据,在本地端就能够使用私钥来进行解密。私钥只有自己拥有。 SSH工作过程:在整个通讯过程中,为实现SSH的安全连接,服务端与客户端要经历如下五个阶段: 版本号协商阶段 SSH目前包括SSH1和SSH2两个版本,双方通过版本协商确定使用的版本 密钥和算法协商阶段 SSH支持多种加密算法,双方根据本端和对端支持的算法,协商出最终使用的算法 认证阶段 SSH客户端向服务器端发起认证请求,服务器端对客户端进行认证 会话请求阶段 认证通过后,客户端向服务器端发送会话请求 交互会话阶段 会话请求通过后,服务器端和客户端进行信息的交互 一、版本协商阶段 服务器端打开端口22,等待客户端连接; 客户端向服务器端发起TCP初始连接请求,TCP连接建立后,服务器向客户端发送第一个报文,包括版本标志字符串,格式为“SSH-<主协议版本号>.<次协议版本号>.<软件版本号>”,协议版本号由主版本号和次版本号组成,软件版本号主要是为调试使用。 客户端收到报文后,解析该数据包,如果服务器的协议版本号比自己的低,且客户端能支持服务器端的低版本,就使用服务器端的低版本协议号,否则使用自己的协议版本号。 客户端回应服务器一个报文,包含了客户端决定使用的协议版本号。服务器比较客户端发来的版本号,决定是否能同客户端一起工作。如果协商成功,则进入密钥和算法协商阶段,否则服务器断开TCP连接。 说明:上述报文都是采用明文方式传输。 二、密钥和算法协商阶段 服务器端和客户端分别发送算法协商报文给对端,报文中包含自己支持的公钥算法列表、加密算法列表、MAC(Message Authentication Code,消息验证码)算法列表、压缩算法列表等等。 服务器端和客户端根据对端和本端支持的算法列表得出最终使用的算法。 服务器端和客户端利用DH交换(Diffie-Hellman Exchange)算法、主机密钥对等参数,生成会话密钥和会话ID。 由此,服务器端和客户端就取得了相同的会话密钥和会话ID。对于后续传输的数据,两端都会使用会话密钥进行加密和解密,保证了数据传送的安全。在认证阶段,两端会使用会话用于认证过程。 会话密钥的生成: 客户端需要使用适当的客户端程序来请求连接服务器,服务器将服务器的公钥发送给客户端。(服务器的公钥产生过程:服务器每次启动sshd服务时,该服务会主动去找/etc/ssh/ssh_host*文件,若系统刚装完,由于没有这些公钥文件,因此sshd会主动去计算出这些需要的公钥文件,同时也会计算出服务器自己所需要的私钥文件。) 服务器生成会话ID,并将会话ID发给客户端。 若客户端第一次连接到此服务器,则会将服务器的公钥数据记录到客户端的用户主目录内的~/.ssh/known_hosts。若是已经记录过该服务器的公钥数据,则客户端会去比对此次接收到的与之前的记录是否有差异。客户端生成会话密钥,并用服务器的公钥加密后,发送给服务器。 ****服务器用自己的私钥将收到的数据解密,获得会话密钥。 服务器和客户端都知道了会话密钥,以后的传输都将被会话密钥加密。 三、认证阶段 SSH提供两种认证方法: 基于口令的认证(password认证):客户端向服务器发出password认证请求,将用户名和密码加密后发送给服务器,服务器将该信息解密后得到用户名和密码的明文,与设备上保存的用户名和密码进行比较,并返回认证成功或失败消息。 基于密钥的认证(publickey认证):客户端产生一对公共密钥,将公钥保存到将要登录的服务器上的那个账号的家目录的.ssh/authorized_keys文件中。认证阶段:客户端首先将公钥传给服务器端。服务器端收到公钥后会与本地该账号家目录下的authorized_keys中的公钥进行对比,如果不相同,则认证失败;否则服务端生成一段随机字符串,并先后用客户端公钥和会话密钥对其加密,发送给客户端。客户端收到后将解密后的随机字符串用会话密钥发送给服务器。如果发回的字符串与服务器端之前生成的一样,则认证通过,否则,认证失败。 注:服务器端对客户端进行认证,如果认证失败,则向客户端发送认证失败消息,其中包含可以再次认证的方法列表。客户端从认证方法列表中选取一种认证方法再次进行认证,该过程反复进行。直到认证成功或者认证次数达到上限,服务器关闭连接为止。实例
-
常见问题 (II)]打印 "无法启动交换机根节点 "错误(该错误会导致系统进入紧急模式)的解决方案。
-
纯干货分享 | 研发效能提升——敏捷需求篇-而敏捷需求是提升效能的方式中不可或缺的模块之一。 云智慧的敏捷教练——Iris Xu近期在公司做了一场分享,主题为「敏捷需求挖掘和组织方法,交付更高业务价值的产品」。Iris具有丰富的团队敏捷转型实施经验,完成了企业多个团队从传统模式到敏捷转型的落地和实施,积淀了很多的经验。 这次分享主要包含以下2个部分: 第一部分是用户影响地图 第二部分是事件驱动的业务分析Event driven business analysis(以下简称EDBA) 用户影响地图,是一种从业务目标到产品需求映射的需求挖掘和组织的方法。 在软件开发过程中可能会遇到一些问题,比如大家使用不同的业务语言、技术语言,造成角色间的沟通阻碍,还会导致一些问题,比如需求误解、需求传递错误等;这会直接导致产品的功能需求和要实现的业务目标不是映射关系。 但在交付期间,研发人员必须要将这些需求实现交付,他们实则并不清楚这些功能需求产生的原因是什么、要解决客户的哪些痛点。研发人员往往只是拿到了解决方案,需要把它实现,但没有和业务侧一起去思考解决方案是否正确,能否真正的帮助客户解决问题。而用户影响地图通常是能够连接业务目标和产品功能的一种手段。 我们在每次迭代里加入的假设,也就是功能需求。首先把它先实现,再逐步去验证我们每一个小目标是否已经实现,再看下一个目标要是什么。那影响地图就是在这个过程中帮我们不断地去梳理目标和功能之间的关系。 我们在软件开发中可能存在的一些问题 针对这些问题,我们如何避免?先简单介绍做敏捷转型的常规思路: 先做团队级的敏捷,首先把产品、开发、测试人员,还有一些更后端的人员比如交互运维的同学放在一起,组成一个特训团队做交付。这个团队要包含交付过程中所涉及的所有角色。 接着业务敏捷要打通整个业务环节和研发侧的一个交付。上图中可以看到在敏捷中需求是分层管理的,第一层是业务需求,在这个层级是以用户目标和业务目标作为输入进行规划,同时需要去考虑客户的诉求。业务人员通过获取到的业务需求,进一步的和团队一起将其分解为产品需求。所以业务需求其实是我们真正去发布和运营的单元,它可以被独立发布到我们的生产环境上。我们的产品需求其实就是产品的具体功能,它是我们集成和测试的对象,也就是我们最终去部署到系统上的一个基本单元。产品需求再到了我们的开发团队,映射到迭代计划会上要把它分解为相应的技术任务,包括我们平时所说的比如一些前端的开发、后端的开发、测试都是相应的技术任务。所以业务敏捷要达到的目标是需要去持续顺畅高质量的交付业务价值。 将这几个点串起来,形成金字塔结构。最上层我们会把业务目标放在整个金字塔的塔尖。这个业务目标是通过用户的目标以及北极星指标确立的。确认业务目标后再去梳理相应的业务流程,最后生产。另外产品需求包含了操作流程和业务规则,具需求交付时间、工程时间以及我们的一些质量标准的要求。 谈到用户影响的地图,在敏捷江湖上其实有一个传说,大家都有一个说法叫做敏捷需求的“任督二脉”。用户影响地图其实就是任脉,在黑客马拉松上用过的用户故事地图其实叫督脉。所以说用户影响地图是在用户故事地图之前,先帮我们去梳理出我们要做哪些东西。当我们真正识别出我们要实现的业务活动之后,用户故事地图才去梳理我们整个的业务工作流,以及每个工作流节点下所要包含的具体功能和用户故事。所以说用户影响地图需要解决的问题,我们包括以下这些: 首先是范围蔓延,我们在整张地图上,功能和对应的业务目标是要去有一个映射的。这就避免了一些在我们比如有很多干系人参与的会议上,那大家都有不同想法些立场,会提出很多需求(正确以及错误的需求)。这个时候我们会依据目标去看这些需求是否真的是会影响我们的目标。 这里提到的错误需求,比如是利益相关的人提出的、客户认为产品应该有的、某个产品经理需求分析师认为可以有的....但是这些功能在用户影响地图中匹配不到对应目标的话,就需要降低优先级或弃掉。另外,通常我们去制定解决方案的时候,会考虑较完美的实现,导致解决方案括很多的功能。这个时候关键目标至关重要,会帮助我们梳理筛选、确定优先级。 看一下用户影响到地图概貌 总共分为一个三层的结构: 第一层why,你的业务目标哪个是最重要的,为什么?涉及到的角色有哪些? 第二层how ,怎样产生影响?影响用户角色什么样的行为? (不需要去列出所有的影响,基于业务目标) 第三层what,最关键的是在梳理需求时不需一次把所有细节想全,这通常团队中经常遇到的问题。 我们用这个例子来看一下 这是一个客服中心的影响地图,业务目标是 3个月内不增加客服人数的前提下能支持1.5倍的用户数。此业务目标设定是符合 smart 原则的,specific非常的具体,miserable 是可以衡量的,action reoriented是面向活动的, real list 也是很实际的。 量化的目标会指引我们接下来的行动,梳理一个业务目标,尽量去量化,比如 :我们通过打造一条什么样的流水线,能够提高整个部署的效率,时间是原来的 1/2 。这样才是一个能量化的有意义的目标。 回到这幅图, how 层级识别出来的内容,客服角色:想要对它施加的影响,把客户引导到论坛上,帮助客户更容易的跟踪问题,更快速的去定位问题。初级用户:方论坛上找到问题。高级用户:在论坛上回答问题。通过我们这些用户角色,进行活动,完成在不增加客户客服人数的前提下支持更多的用户数量。 最后一个层级,才是我们日常接触比较多的真正的功能的特性和需求,比如引导到客户到论坛上,其实这个产品就需要有一个常见问题的论坛的链接。这个层次需要我们团队进一步地在交付,在每个迭代之前做进一步的梳理,细化成相应的用户故事。 这个是云智慧团队中,自己做的影响地图的范例,可以看下整个的层级结构。序号表示优先级。 那我们用户影响地图可以总结为:
-
Grid++Report 锐浪报表开发常见问题解答集锦-报表设计 问:怎样在设计时打印预览报表? 答:为了及时查看报表的设计效果,Grid++Report 报表设计应用程序提供了四种查看视图:普通视图、页面视图、预览视图与查询视图。通过窗口下边的 Tab 按钮可以在四种视图中任意切换。在预览视图中查看报表的打印预览效果,在查询视图中查看报表的查询显示效果。如果在报表的记录集提供了数据源连接串与查询 SQL,在进入预览视图与查询视图时会利用数据源连接串与查询 SQL 从数据源中自动取数,否则 Grid++Report 将自动生成模拟数据进行模拟打印预览与查询显示。注意:在预览视图与查询视图中看到的报表运行结果有可能与在你程序中的最终运行结果有差异,因为在报表的生成过程中我们可以在程序中对报表的生成行为进行一定的控制。 问:怎样用 Grid++Report 设计交叉表? 答:Grid++Report 没有提供专门实现交叉表的功能,其它的报表构件提供的交叉表功能一般也比较死板和功能有限。利用 Grid++Report 的编程接口可以做出灵活多变,功能丰富的交叉表。示例程序 CrossTab 就是一个实现交叉表的例子程序,认真领会此例子程序,你就可以做出自己想要各种交叉表,并能提取一些共用代码,便于重复使用。 问:怎样设置整个报表的缺省字体? 答:设置报表主对象的字体属性,也就是设置了整个报表的缺省字体。如果改变报表主对象的字体属性,则没有专门的设置字体属性的子对象的字体属性也跟随改变。同样每个报表节与明细网格也有字体属性,他们的字体属性也就是其拥有的子对象的缺省字体。 问:怎样在打印时限制一页的输出行数? 答:设定明细网格的内容行的‘每页行数(RowsPerPage)’属性即可。另外要注意‘调节行高(AdjustRowHeight)’属性值:为真时根据页面的输出高度自动调整行的高度,使整个页面的输出区域充满。为假时按设计时的高度输出行。 问:怎样显示中文大写金额? 答:将对象的“格式(Format)”属性设为 “$$” 及可,可以设置格式的对象有:字段(IGRField)、参数(IGRParameter)、系统变量(IGRSystemVarBox)与综合文字框(IGRMemoBox),其中综合文字框是在报表式上设格式。 问:能否实现自定义纸张与票据打印? 答:Grid++Report 完全支持自定义纸张的打印,只要在报表设定时在页面设置中选定自定义纸张,并指定准确的纸张尺寸。当然要在最终输出时得道合适的打印结果,输出打印机必须支持自定义纸张打印。Windows2000/XP/2003 操作系统上可以在打印机上定义自定义纸张,也可以采用这种方式实现自定义纸张打印。 问:怎样实现 0 值不打印? 答:直接设置格式串就可以,在“数字格式”设置对话框中选定“0 不显示”,就会得到合适的格式串。也可以通过直接录入格式串来指定 0 不显示,但格式串必须符合 Grid++Report 的规定格式。另一种实现办法是在报表获取明细记录数据时,在 BeforePostRecord 事件中将值为零的字段设为空,调用字段的 Clear 方法将字段置为空。 问:怎样实现多栏报表? 答:在明细网格上设‘页栏数(PageColumnCount)’属性值大于 1 即可。通过 Grid++Report 的“页栏输出顺序”还可以指定多栏报表的输出顺序是“先从上到下”还是“先从左到右”。 问:如何实现票据套打? 答:Grid++Report 为实现票据套打做了很多专门的安排:报表设计器提供了页面设计模式,按照设定的纸张尺寸显示设计面板,如果将空白票据的扫描图设为设计背景图,在定位报表内容的输出位置会非常方便。报表部件可以设定打印类别,非套打输出的内容在套打打印模式下就不会输出。 问:Grid++Report 有没有横向分页功能? 答:回答是肯定的,在列的总宽度超过打印页面的输出宽度时,Grid++Report 可以另起新页输出剩余的列,如果左边存在锁定列,锁定列可以在后面的新页中重复输出,这样可以保证关键数据列在每一页都有输出。仔细体会 Grid++Report 提供的多种打印适应策略,选用最合适的方式。Grid++Report 的多种打印适应策略为开发动态报表提供了很好的支持。 问:怎样实现报表本页小计功能? 答:定义一个报表分组,将本分组定义为页分组,在本分组的分组头与分组尾上定义统计。页分组就是在每页产生一个分组项,在每页的上端与下端都会分别显示页分组的分组头与分组尾,页分组不用定义分组依据字段。 报表运行 问:怎样与数据库建立连接? 答:如果在设计报表时指定了数据集的数据源连接串与查询 SQL 语句,Grid++Report 采用拉模式直接从数据源取得报表数据,Grid++Report 利用 OLE DB 从数据源取数,OLE DB 提供了广泛的数据源操作能力。如果 Grid++Report 的数据来源采用推模式,即 Grid++Report 不直接与数据库建立连接,各种编程语言/平台都提供了很好的数据库连接方式,并且易于操作,应用程序在报表主对象(IGridppReport)的 FetchRecord 事件中将数据传入,例子程序提供了各种编程语言填入数据的通用方法,对C++Builder 和 Delphi 还进行了专门的包装,直接关联 TDataSet 对象也可以将 TDataSet 对象中的数据传给报表。 问:打印时能否对打印纸张进行自适应?支持表格的折行打印吗? 答:Grid++Report 在打印时采用多种适应策略,通过设置明细网格(IGRDetailGrid)的‘打印策略(PrintAdaptMethod)’属性指定打印策略。(1)丢弃:按设计时列的宽度输出,超出范围的内容不显示。(2)绕行:按设计时列的宽度输出,如果在当前行不能完整输出,则另起新行进行输出。(3)缩放适应:对所有列的输出宽度进行按比例地缩放,使总宽度等于页面的输出宽度。(4)缩小适应:如果列的总宽度小于页面的输出宽度,对所有列的输出宽度进行按比例地缩小,使总宽度等于页面的输出宽度。(5)横向分页:超范围的列在新页中输出。(6)横向分页并重复锁定列。 问:如何改变缺省打印预览窗口的窗口标题? 答:改变报表主对象的‘标题(Title)’属性即可。 问:利用集合对象的编程接口取子对象的接口引用,但不是自己期望的结果。 答:Grid++Report中所有集合对象的下标索引都是从 1 开始,另按对象的名称查找对象的接口引用时,名称字符是不区分大小写的。 问:怎样在运行时控制报表中各个对象的可见性?即怎样在运行时显示或隐藏对象? 答:在报表主对象(GridppReport)的 SectionFormat 事件中设定相应报表子对象的可见(Visible)属性即可。 问:报表主对象重新载入数据,设计器中为什么没有反映新载入的数据? 答:应调用 IGRDesigner 的 Reload 方法。 问:怎样实现不进入打印预览界面,直接将报表打印出来?