
用户发我这个问题的时候我第一反应是熟悉。做SAP这块的尤其经常帮业务部门处理Excel导入、跑批量程序的老顾问几乎都撞上过这两行提示。一个是在WPS里填得好好的模板传到SAP里直接被弹回来提示“文档中不包含数据”另一个是同一个程序跑第二次时系统冷冰冰地甩一句“程序正在运行中”。单看字面一个像是在说你的文件有问题一个像是在说系统忙不过来。其实两个问题的根子都不在字面意思上处理起来也不难但如果不搞清楚背后的机制很容易像无头苍蝇一样来回试。这篇文章我不打算只给操作步骤我尽量把这两类问题的来龙去脉、排查逻辑讲透再给一套可以直接照做的流程。适合刚入行的SAP顾问、企业内部IT支持以及被这两个报错反复折磨的超级用户看。1. 先放在一起看这两个报错的本质并不是“文件坏了”或“系统忙”先说第一个报错。“文档中不包含数据”这句话最坑人的地方就是它让人下意识去怀疑文件内容于是很多人会反复打开WPS确认数据还在不在然后重新保存、重新上传折腾半天发现还是报同样的错。其实SAP想表达的意思更接近“我没能从你给的这个文件里解析出可用数据”至于文件里到底有没有内容SAP并不关心。也就是说这不是文件是否“有数据”的问题而是文件格式、编码、结构是否符合SAP解析规则的问题。第二个报错“程序正在运行中”字面理解是系统告诉你某个程序还在跑。但实际场景里大量情况是程序明明已经结束了界面上也关掉了但系统依然认为它还在运行。这背后其实是SAP对并发控制的一种锁机制。SAP不允许同一个程序在同一个系统里被重复执行或者说不允许可能产生数据冲突的操作同时进行。当一个程序异常退出、会话没有正常释放、或者更新进程卡住时锁没有解开再跑第二次自然就会收到这个提示。把这两个问题放在一起看共通点很有意思它们都是SAP对外部输入或内部状态的“契约检查”。文件解析有一套格式契约程序执行有一套状态契约。契约没满足系统就给你一个看起来莫名其妙、实则逻辑清晰的提示。搞懂了这个前提后面的排查思路就顺了。2. “文档中不包含数据”先搞清楚SAP到底是怎么读你那个Excel的要理解这个报错首先得知道SAP是怎么读取上传文件的。传统GUI环境下SAP不是自己去解析Excel文件的二进制内容而是借助前端电脑上的Excel组件OLE/COM接口或者内置的表格解析器来读取。你点“上传”按钮SAP前端会把文件交给解析组件解析组件按Excel的标准格式逐行读取单元格再传回SAP后端处理。这里就出现了一个很关键的隐患解析组件“按标准Excel格式”读取。如果你的文件是用WPS生成的而WPS在保存时没有完全按照Excel标准写入文件内部结构解析器就可能出现两种情况一是直接读不到任何单元格数据二是读到的数据类型跟预期不一致。实际处理中我碰到最多的几个具体原因可以归成三类。原因类别典型表现为什么SAP读不到伪Excel文件文件扩展名是.xls或.xlsx实际是网页另存为的HTML或用WPS另存为“.et”等专用格式解析器按Excel二进制或XML包结构解析打开一看结构不对自然认为没有数据数据结构问题有合并单元格、表头占多行、有空行空列、多个Sheet且第一个Sheet是空的解析器默认读取活动Sheet或指定Sheet如果读取区域是空的就报“无数据”单元格格式问题数字以文本形式存储、单元格内包含换行或首尾空格、单元格格式类型标记异常解析器按数据类型重新解释时把内容丢弃或判定为不可用2.1 最常见的元凶WPS保存时把文件变成了“伪Excel”我处理过的案例里十个里面至少有五六个是这个问题。操作过程通常是这样用户从网页、系统或者某个地方复制了一段数据粘贴进WPS然后直接按CtrlS保存。WPS如果识别到这段数据的来源是网页有时默认保存格式不是真正的Excel工作簿而是“网页”或“Excel可编辑网页”之类的格式。从文件图标上看好像还是Excel表格的样子甚至用户自己双击打开也完全正常。但文件的实际内容已经不是标准Excel结构SAP的解析器打开后找遍整个文件都发现不了有效的单元格区域于是报“文档中不包含数据”。还有一种情况是用户在图方便时选了WPS自带的表格格式如.et、.ett。这类文件在WPS里打开毫无问题但SAP根本不在可识别文件类型列表里。你选文件时如果开了“所有文件”过滤能选中这个文件但解析时就只能得到空结果。2.2 表头和合并单元格看着没问题读起来全是“坑”另一个高发原因藏在模板设计里。SAP的导入模板通常对表头位置有严格要求比如第一行必须是字段名然后从第二行开始才是数据。但业务人员用WPS填模板时习惯上会先加一个标题行比如“某某公司物料主数据导入表”再合并单元格、调整格式让表格看起来更清楚。这种文件交给SAP时解析器把标题行当作表头或者因为合并单元格导致单元格值读取错位结果就是数据行全部错乱最终被认为没有有效数据。还有更隐蔽的有多个Sheet时第一个Sheet是空白的说明页或者封面页数据实际写在第二个Sheet里。SAP默认读取第一个Sheet或者用户指定名称的Sheet读到一个空表直接就报“文档中不包含数据”。很多用户这时候会非常委屈明明数据都在只是不在第一个工作表里。2.3 文本型数字和特殊字符数据格式导致的数据丢失第三个常见原因是单元格格式问题。WPS里如果一列数字被设置成“文本”格式或者从网页复制过来后自动变成了文本型数字左上角有绿色小三角标记在SAP解析时会被当成字符串处理。如果SAP那边的字段期望的是数值解析器可能跳过或丢弃这些内容。更麻烦的是某些单元格看起来是空的实际上里面带着不可见字符比如复制粘贴时带进来的换行符、首尾空格这类内容在文件解析时也算单元格数据会让数据行读取错位打乱整个导入逻辑。3. 排查“文档中不包含数据”的标准动作按这个顺序走遇到这个报错我不建议上来就改数据而是先验证文件本身。下面这套流程是我自己处理过几十个类似问题后固定下来的标准化动作照着走完基本能定位九成以上的问题。3.1 第一步先验文件“真身”别信扩展名拿到报错文件先确认它到底是真Excel还是伪Excel。右键点击文件查看“属性”看“打开方式”和“文件类型”是不是显示为Excel/WPS表格。更可靠的办法是把文件扩展名先显示出来Windows资源管理器里勾选“文件扩展名”然后把这个文件复制一份把扩展名改成.zip。如果文件是真xlsx格式改完扩展名后能正常解压里面能看到xl文件夹、工作簿XML等标准结构。如果文件实际上是HTML或者别的格式解压直接失败。没有把握的话还有个更简单的土办法用记事本打开文件。真Excel文件打开后是乱码但伪Excel文件尤其是HTML格式打开后能看到一堆HTML标签甚至能直接看到表格里的文字内容。看到这种情况基本就可以断定问题出在这里。3.2 第二步用WPS重存为标准Excel格式确认文件格式有问题后处理办法很简单用WPS打开文件点“文件”菜单下的“另存为”把文件类型明确选为“Excel工作簿.xlsx”或“Excel 97-2003工作簿.xls”然后重新保存。注意不要选“WPS表格文件.et”也不要选“单个文件网页.mht”。保存完之后建议用同样的验证方法确认一下新文件已经是标准Excel结构再拿去SAP里传。这里有个细节如果原来的伪Excel文件里有复杂的网页脚本、样式代码直接另存为xlsx时WPS可能会弹提示说部分格式将发生变化这是正常的确认即可。另存为后最好重新打开一次确认数据都在再上传。3.3 第三步清理Sheet、表头和单元格格式确认文件格式没问题但依然报“文档中不包含数据”就要看表格结构了。打开文件按这个顺序检查当前文件有几个工作表把多余的空表删掉把有数据的表移到第一个位置。第一行是不是必须是字段名如果是把上面的标题行、空行删除取消合并单元格。全选数据区域检查第一行前有没有隐藏行、空行数据区域中间有没有整行整列为空的情况有就删掉。选中所有数据列检查单元格格式。文本型数字先转成常规格式选中列点“数据”菜单的“分列”直接点完成即可。去掉单元格内首尾空格可以用WPS的“查找替换”把空格替换掉或者用TRIM函数生成一列新的干净数据。检查每一列的第一个单元格是否有列标题列标题不要用合并单元格不要带特殊字符建议只用字母、数字和下划线。3.4 第四步把文件放到英文路径下再传这一点常被忽略但非常值得做。SAP GUI的文件读取组件在解析中文路径下某些文件时可能出现异常尤其是文件名里带空格、括号、井号的情况。建议在C盘根目录建一个纯英文的临时文件夹比如“C:\Upload”把文件改成简单的英文名再上传。这一步不需要100%理解背后的原因但实测下来确实能解决一部分“文件明明正常但SAP读不出来”的疑难杂症。3.5 第五步用最小样本测试如果以上四步走完还是报错不要继续在完整文件上死磕。新建一个只有3行数据、1个Sheet、字段名齐全的极简xlsx文件先传一次。如果极简文件能传过去说明问题出在原文件的内容或格式细节上如果极简文件也报同样的错那问题可能出在SAP这边的模板定义或者事务代码的配置上这时候就该去检查SAP侧的上传模板、文件格式设置是否匹配别再把时间浪费在捣鼓文件上。4. “程序正在运行中”这个提示背后是SAP的并发锁机制再来看第二个报错。在SAP里“程序正在运行中”来自系统对程序并发执行的控制机制。简单说SAP通过锁对象、批处理会话、后台作业状态等几个维度来记录“某个程序当前是否处于活动状态”。如果状态记录没有被及时清除当你再次运行同一个程序时系统就会认为这个程序还在运行拒绝启动新实例。为什么状态记录会残留最常见的几个场景如下程序在执行过程中异常终止比如用户强行关闭SAP GUI、网络断线、程序运行时崩溃后台记录的锁没有正常释放。这很像电脑上的程序崩溃后系统还残留着一个卡住的进程。批处理输入会话SM35里的会话处理到一半停在“处理中”状态没有走完也没有被标记为完成或错误。程序触发了后台作业作业显示“正准备”或“正在运行”但实际进程已经不存在了。后台更新请求SM13卡住比如KO88结算这类有更新操作的程序更新进程异常后相关的锁一直挂着。程序代码里有用户增强比如KO88的用户增强增强代码里加了COMMIT WORK或CALL TRANSACTION但没有正确处理锁的释放导致程序反复执行时互相锁住。理解了机制就要明白处理这个报错的核心思路不是去“绕过”系统而是找到那个残留的状态记录把它清理掉让系统恢复对程序状态的正确认知。5. “程序正在运行中”的完整排查链路六步检查法下面这套排查顺序是从最可能、最简单的场景往最复杂、最需要谨慎操作的场景推进的。建议严格按顺序来每一步都先确认再操作。5.1 第一步SM35查看批处理输入会话事务码SM35能查所有批处理输入会话。进入后关键是看会话状态。如果看到状态是“正在处理”的会话而且时间已经很长没变化这个会话基本就是卡住的。处理方法有两种如果确定这个会话不需要了选中它菜单里选择“删除”系统会释放对应锁如果会话需要重新执行先标记删除再重新插入或直接重新处理。处理完这一步很多“程序正在运行中”就已经解决了因为系统在运行某些导入程序时锁就是挂在批处理会话上的。5.2 第二步SM37检查后台作业如果报错的程序是作为后台作业调度的去SM37里查看当前用户或所有用户的作业列表。重点看“已释放”“正在运行”这两个状态的作业。如果一个作业显示正在运行等你点进去看JOB日志时发现根本没有任何动态记录或者运行了很长时间还没结束很可能是作业状态假死。处理方法是用SM37里的“取消”功能只能取消已释放的作业或者用“实时处理”方式把作业重新处理。如果作业显示“已完成”但程序还是说在运行那问题不在后台作业层面继续往下查。5.3 第三步SM50或SM66查看进程SM50看当前应用服务器实例的进程SM66可以看整个系统所有服务器实例的进程。进入后按进程类型过滤通常看对话进程、更新进程和后台进程。找到正在运行的程序名报表名或者事务码确认它是不是真的在跑。如果进程卡在“正在运行”但CPU占用为零、时间长了没变化一般是异常进程需要管理员权限的话可以在SM50里直接双击进程然后选择“结束会话”。这一步操作要非常谨慎务必确认不是别人正在正常操作的数据否则贸然结束进程可能导致数据不一致。5.4 第四步SM13查看更新请求如果报错的程序涉及过账、结算例如KO88、CO88、MR22这类财务操作需要去SM13看更新请求。重点看状态为“更新尚未执行”或“正在执行”的请求。如果更新请求确实卡住了可以在SM13里选中请求通过菜单“编辑→重置更新”把相关条目恢复初始状态或者手动执行更新。处理完卡住的更新请求后程序占用的锁会自动释放。5.5 第五步SM12查看锁对象如果上面几步都没找到问题那大概率是有ABAP锁没释放。SM12可以查看系统里所有的锁条目按用户名、表名或锁对象名筛选。比如报错的程序名是ZMM018就筛选锁对象名称或者关联的表。找到锁条目后先查看“客户端”“用户名”“事务代码”这些信息确认这个锁是残留锁而不是别人正在用的锁确认可以清理后再删除。要注意直接删除锁是有风险的锁对象可能关联着未完成的数据操作删锁前最好评估一下影响面。5.6 第六步查增强代码中的锁逻辑如果用的程序带有用户增强比如某些用户提到过的KO88增强之类而每次跑完程序后都有可能出现锁残留、第二次运行就报“程序正在运行中”那问题很可能是增强代码中ENQUEUE加锁和DEQUEUE解锁不成对。这属于代码层面的问题需要ABAP开发介入。常规处理方法有两种一是代码中增加异常处理确保程序退出前无条件DEQUEUE二是在程序开头用锁检查但不强制加锁或者改用数据库层的“非独占检查”。这个属于开发的后续优化不是IT运维能一步搞定的。6. 别等问题发生才处理日常运维中怎么减少这两类报错处理过太多次同类问题之后我在团队内部定了一套操作约定虽然不能保证百分之百杜绝报错但确实把问题发生频率压低了非常多。6.1 模板管理上“一刀切”所有需要Excel导入的SAP模板统一由IT和关键用户维护标准版业务人员不允许自己新建空白表再往里粘贴数据。标准模板的Sheet名称、表头、格式都固定好下发时同时发一份填写说明。这一条看起来简单却是最有效的手段。大量“文档中不包含数据”的报错根源都在于用户自己改造了模板而不是文件本身有问题。6.2 上传文件前“三查三改”我让团队每个人在导入前都养成这个习惯一查扩展名文件必须是.xls或.xlsx别用.et、.mht。二查工作表数据必须在第一个Sheet第一个Sheet第一行必须是字段名。三查路径文件放在英文路径下文件名用英文。一改把数据区域里的合并单元格全部取消。二改把文本型数字通过分列改成常规格式。三改能不用中文和特殊字符就不用尤其不要带表情符号、全角括号。6.3 跑批量程序前“三确认”确认SM37里没有同一个程序的旧作业在运行或排队。确认SM35里没有遗留的批处理会话。确认上次运行或者测试运行的程序进程已经彻底退出。如果这三条都确认没问题再运行大批量生产程序基本不会再撞上“程序正在运行中”。而且养成这个习惯还有一个额外好处能顺带发现很多潜在的数据重复处理问题避免因为重复运行导致数据重复过账。6.4 有条件的话用Web端上传工具替代传统GUI如果公司网络环境允许我建议评估一下将Excel导入类操作迁移到Web端工具比如SAP Fiori应用、自开发的Web上传页面。Web端上传组件对文件格式的容错性更好能直接给出更友好的错误提示而且不依赖前端电脑的Excel组件WPS与SAP的兼容问题会大幅减少。这算是一个从上到下解决问题的思路短期内在传统GUI上折腾文件格式当然可行但长期看换个更现代的上传通道才是治本的办法。其实这两个报错处理得多了我自己最大的感受是SAP的这些提示信息并没有人们想得那么“不可理喻”它们其实都是有一定的排错导向的只是需要先了解它的机制。遇到“文档中不包含数据”先怀疑文件和格式是否符合契约而不是去怀疑数据没填。遇到“程序正在运行中”先去找残留的会话、作业、进程、锁而不是去反复重跑同一个程序。遵循这个思路问题基本都能在几分钟内被拆解掉。