科目挂核算项目的业务在总帐与基础资料部分涉及的范围比较广, 如果对应此部分的后台数据发生错乱,则会导致软件无法正常进行,下面对常见报错进行了汇总,用户可以在学习完基础数据结构与逻辑的基础上自行进行分析与处理,从而解决问题。
1、科目设置了核算项目,在凭证录入时不提示需要输入核算
2、科目设置了核算项目,在凭证查询时,看不到核算项目信息
3、在科目余额表中无法查看核算项目明细,但未过账前在包括未过账凭证时可以正常显示
4、无法结转损益,提示分录缺少核算项目
5、凭证无法过账,提示分录缺少核算项目
6、账薄查询时,提示 F3001 列无效
7、凭证过账时提示:在结果列中多次出现列名 F1
8、应收应付系统初始化转余额到总账失败
9、其他凭证模板如自动转账、各类型的单据模板等生成凭证失败
10、修改核算项目明细时,提示定义的应用程序或对象错误
11、单据录入时 F7 无法调出客户或者供应商
12、科目余额表有部分供应商显示两行数据,正确数据为这两行数据之和,供应商编码相同上述错误,都是因为与 Fdetailid 值相关的记录不正确造成的。比照数据逻辑进行处理。另外,即使同样的报错,执行处理的语句也会因不同帐套或不同期间而略有不同,请一定在理解基础数据结构与逻辑的基础上进行处理。
基础数据结构与逻辑
1.核算项目类别
增加一核算项目类别,一般先在 t_itemclass 中生成记录,如果新生成的核算项目类别有具体的属性则会继续在 t_itempropdesc 中生成记录,同时在对应的 t_itemclass 中的 Fsqltablename中会为对应的类别生成一个具体的数据表来记录它的专有属性。 例如: 新增一个核算项目类别“银行” ,包括的属性有银行的代码、名称、地址、区域。如下图:
则 t_itemclass 表中会发生如下变化:
注:Fitemclassid(核算项目类别内码) 。代表不同的核算项目类别,1 为客户,2 为部门,3为职员,4 为物料,5 为仓库,6 为备注,7 为计量单位,8 为供应商,9 为现金流量项目…如果是自定义的核算项目,一般 Fitemclassid 字段的值都比较大,一般均在 3001 以后。t_itemclass 是保存核算项目类别的一些共有属性的,如 Fnumber 代表核算项目类别的代码,Fname 代表名称,另外有一个 FsqlTableName 字段,它表示每个核算项目对应的详细情况表名称,由图可见银行类对应的核算项目详细情况表为 T_item_3001,这个稍后作介绍。
由于我们还定义了银行类的一些专有属性,所以在 t_itempropdesc 中会有如下变化:
t_itempropdesc 表是通过 Fitemclassid 与 T_itemclass 联系的,这里对应 Fitemclassid 为 3001的共有 4 条记录,就是我们刚才定义的银行类的专有属性,其中字段 fsqlcolumnname 为四个属性分别在核算项目详情表 T_item_3001 对应的字段。
2.核算项目
具体的核算项目是保存在表 t_item 中的,若核算项目类还有专有属性,则其专有信息保存在 t_itemclasss 中 FsqlTableName 对应的表中。在核算项目类银行下新增一核算项目明细,如图:
此时,在 t_item 表中会增加一条明细,如下图第 64 条记录:
同时在保存该核算项目详细情况的表中会增加以下一条记录:
以上两表是通过 fitemid(核算项目内码)进行关联的。
3.核算项目横纵表
核算项目横表:涉及的表为 t_ItemDetail,此表是联接各个核算项目业务表的纽带,如科目表,凭证表,余额表等等都与此表有很大的联系。核 算 项 目 纵 表 为 t_ItemDetailV , 此 表 是 由 核 算 项 目 横 表 来 生 成 的 , 可 以 用SP_CleanItemDetailV 这个存储过程来生成 。是核算项目横表另一种形式的表现。在平时的各种报表计算时,程序是直接关联的该表。下面我们以一实例来说明核算项目横纵表是如何来管理核算项目的:在科目应收账款下挂客户的核算项目类别,则在 t_itemdetail 中会出现如下记录:
其中 fdetailid 为核算项目组合内码,fdetailcount 代表核算项目组合数目,后面的以 F 开头的类分别代表该组合的具体内容, 上图中的 fdetailid=1 的记录就代表某一科目下挂一个核算项目类,该类为客户,其中 F 后面的数字具体代表什么类别是根据 t_itemclass 中核算项目类别对应的 fitemclassid 来决定的。如下图:
t_itemclass 与 t_itemdetail,t_itemdetailv 的关系:
同时我们也会看到科目表 t_account 中关于应收账款的记录作了如下变化:
t_account 中应收账款对应的 fdetailid 字段由未挂核算项目前的 0 变为了 1,也就是说进行了核算项目管理的科目的具体情况, 都可以通过该表中的这个字段来表示, 该字段与核算项目横表是一一对应的。
如果我们在录入凭证的时候选择了科目下的具体核算项目,如图:
其中 f1 下面的 64 代表核算项目 t_item 表中 fitemid 为 64 的核算项目, 即我们在凭证录入时候选择的核算项目。
该凭证在凭证分录表中保存信息如下:
当该凭证过帐时,科目余额表中也会保存不同币别的两条相应的记录:
也就是说对于核算项目横表中 FX 列对应的不是 0 或者-1 的 fdetailid 会在凭证表与科目表中
被引用,对于-1 的则被科目表所引用。
以下 Fdetailid 只能为科目属性值使用,即只能出现在 t_account 表中:
select * from t_itemdetail
where fdetailid in (select Fdetailid from t_itemdetailv
where fitemid=-1)
以下 Fdetailid 只能出现在各余额表、凭证分录表中:
select *from t_itemdetail
where fdetailid in (select Fdetailid from t_itemdetailv where fitemid<>-1)
另外:在 t_itemdetail 中有一条 fdetail 为 0 的记录,这条记录是系统预设的,不能丢失,
丢失了要手工参照标准帐套补入,否则会导致无法过帐,不能正常查看帐簿等问题。此外还
不允许在 Fx 列中出现 NULL 值。如果出现 Null 值,一般都是该表的约束或默认值值丢失,
需要更正:
update t_itemdetail set F3003=0 where F3003 is null
ALTER TABLE t_ItemDetail ALTER column F3003 int NOT NULL
综上,核算项目横纵表与各数据表之间的关系可以通过下图来表示:
案例
1. 修改客户的核算项目明细时报“定义的应用程序或对象错误” ,或录入单据时候 F7 调不
出数据:
这种情况很有可能是保存客户详细记录的表 t_Organization 中记录丢失,可在查询分析
器中执行如下语句补入:
insert into t_Organization(Fitemid,Fnumber,Fparentid,Fshortnumber)
select Fitemid,Fnumber,Fparentid,Fshortnumber
from t_item
where fitemclassid=1 and fdetail=1
and fitemid not in (select fitemid from t_Organization)
update t_Organization set Fregionid=0,ftrade=0,Fvalueaddrate=0,Fsaleid=0
where fitemid in (select fitemid from t_item where fdetail=1)
update a set a.fname=b.fname
from t_Organization a join t_item b on a.fitemid=b.fitemid
同理,其他核算项目类别下的明细表记录丢失,也可模仿此语句补入。
2. 凭证无法过账、账薄报表无法查询、无法结转损益结转损益之后无法过帐或仍有余额,
提示:在结果列中多次出现 F1,名称或代码已存在等
一般是 fdetailcount 数目不对或者相同的核算项目组合出现重复,
对于错误的 fdetailcount,首先要执行如下语句进行更新:
exec sp_cleanitemdetailv–横表生成纵表的存储结构
update a set a.fdetailcount=b.Fcount
from t_itemdetail a join
(select Fdetailid,count(Fitemid) Fcount
from t_itemdetailv
where fitemid<>0 group by Fdetailid) b
on a.fdetailid=b.fdetailid–更新 fdetailcount
exec sp_cleanitemdetailv–重新生成纵表
作了以上更新后发现表中还存在相同组合的重复记录,这是不允许的:
图中 f2=-1 的记录一共有两条,对应的 fdetailid 分别为 8,224,其在科目表 t_account
引用状况如下:
而我们只需要保留一个 fdetailid 即可,此时我们取最小的 fdetailid,执行如下语句更新
科目表:
update t_account
set Fdetailid =(select min(fdetailid) from t_itemdetail
where fdetailid in (select Fdetailid from t_itemdetailv
where fitemid=-1)
and Fdetailcount=1 and F2=-1 )
where Fdetailid in (select (fdetailid) from t_itemdetail
where fdetailid in (select Fdetailid from t_itemdetailv
where fitemid=-1)
and Fdetailcount=1 and F2=-1 )
执行之后科目表更新为以下状况:
同时我们还要删除核算项目横表中的多余记录,执行如下语句:
delete from t_itemdetail
where Fdetailid in(select (fdetailid) from t_itemdetail
where fdetailid in (select Fdetailid from t_itemdetailv
where fitemid=-1)
and Fdetailcount=1 and F2=-1 )
and Fdetailid <>(select min(fdetailid) from t_itemdetail
where fdetailid in (select Fdetailid from t_itemdetailv
where fitemid=-1)
and Fdetailcount=1 and F2=-1 )
exec sp_cleanitemdetailv–重新生成纵表
执行之后核算项目横表 itemdetail 中多余的 fdetailid=224 的记录被删除
另外还要查看各余额表中有没有非法的 fdetailid,即不在核算项目横纵表中的,有的话
则需要删除:
–查找科目余额表中有没有非法的 fdetailid
select * from t_balance
where fdetailid not in (select fdetailid from t_itemdetail)
–删除科目余额表中非法的 fdetailid
delete from t_balance
where fdetailid not in (select fdetailid from t_itemdetail)
同理进行以下操作
查找数量余额表中有没有非法的 fdetailid
select * from t_quantitybalance
where fdetailid not in (select fdetailid from t_itemdetail)
删除数量余额表中非法的 fdetailid
delete from t_quantitybalance
where fdetailid not in (select fdetailid from t_itemdetail)
查找损益类科目实际发生额表中有没有非法的 fdetailid
select * from t_profitandloss
where fdetailid not in (select fdetailid from t_itemdetail)
删除损益类科目实际发生额表中有没有非法的 fdetailid
delete from t_profitandloss
where fdetailid not in (select fdetailid from t_itemdetail)
3. 查询账薄时提示列名 ‘f3001’ 无效出现如上报错则需要查看 t_itemdetail 表中该对
应的列是否存在,如果不存在,应该补充执行如下语句:
If Not Exists(Select c.Name from syscolumns c,sysobjects o
where c.Id=o.Id and c.name='F3001' and o.name='t_ItemDetail')
Begin
Alter Table t_ItemDetail Add F3001 int not null default(0)
Create Index ix_ItemDetail_3001 On t_ItemDetail(F3001)
END
4. 科目余额表过滤本期,科目选择'应付帐款',显示核算项目,确定.
报表显示有部分供应商显示两行数据,正确数据为这两行数据之和,供应商编码相同.例:供
应商代码 2001.0001 这种情况一般是由于核算项目横表中被凭证表, 余额表引用的核算项目
组合有重复记录,如下图:
象这种情况,需要做如下处理:
(1)创建临时表 t_itemdetail_error,把重复核算项目记录插入该表
select a.*, a.fdetailid Fdetailid_temp
into t_itemdetail_error
from t_itemdetail a join t_itemdetail b on a.f8=b.f8 and
a.fdetailcount=b.fdetailcount
where a.fdetailcount=1 and a.fdetailid<>b.fdetailid
and a.f8>0
order by a.f8
(2) 在临时表 t_itemdetail_error 中修改错误的 fdetailid 值 (以最小的 fdetailid 值为
基准) :
update b set b.fdetailid_temp=a.fdetailid
from t_itemdetail_error a join t_itemdetail_error b on a.f8=b.f8 and
a.fdetailcount=b.fdetailcount
where a.fdetailcount=1 and a.fdetailid
and a.f8>0
(3)创建余额表临时表 t_balance_temp :
select * into t_balance_temp from t_balance
order by fyear,fperiod,faccountid,fdetailid,fcurrencyid
(4)更新余额表临时表的错误 detailid 值:
update a set a.fdetailid=b.fdetailid_temp
from t_balance_temp a join t_itemdetail_error b on a.fdetailid=b.fdetailid
(5)创建临时表 temp002:
select top 0 * into temp002 from t_balance
(6)合并 t_balance_temp 相同核算项目项的金额,把结果插入 temp002:
insert into temp002
(fyear,fperiod,faccountid,fdetailid,fcurrencyid,FFrameWorkID,
FBeginBalanceFor,FDebitFor,FCreditFor,FYtdDebitFor,FYtdCreditFor,FEndBalanc
eFor,
FBeginBalance,FDebit,FCredit,FYtdDebit,FYtdCredit,FEndBalance)
select fyear,fperiod,faccountid,fdetailid,fcurrencyid,FFrameWorkID,
sum(FBeginBalanceFor)FBeginBalanceFor,sum(FDebitFor)FDebitFor,sum(FCreditFor)FC
reditFor,
sum(FYtdDebitFor)FYtdDebitFor,sum(FYtdCreditFor)FYtdCreditFor,sum(FEndBalanceFo
r)FEndBalanceFor,
sum(FBeginBalance)FBeginBalance,sum(FDebit)FDebit,sum(FCredit)FCredit,sum(FYtdD
ebit)FYtdDebit,
sum(FYtdCredit)FYtdCredit,sum(FEndBalance)FEndBalance
from t_balance_temp
group by fyear,fperiod,faccountid,fdetailid,fcurrencyid,FFrameWorkID
(7)清空 t_balance 数据 :
delete from t_balance
(8)把 temp002 的值写回 t_balance:
insert into t_balance
(fyear,fperiod,faccountid,fdetailid,fcurrencyid,FBeginBalanceFor,FDebitFor,FCre
ditFor,FYtdDebitFor,
FYtdCreditFor,FEndBalanceFor,FBeginBalance,FDebit,FCredit,FYtdDebit,FYtdCredit,
FEndBalance,FFrameWorkID)
select
fyear,fperiod,faccountid,fdetailid,fcurrencyid,FBeginBalanceFor,FDebitFor,FCred
itFor,FYtdDebitFor,
FYtdCreditFor,FEndBalanceFor,FBeginBalance,FDebit,FCredit,FYtdDebit,FYtdCredit,
FEndBalance,FFrameWorkID
from temp002
(9)删除 t_itemdetail 中的重复值:
delete from t_itemdetail
where fdetailid in (select fdetailid from t_itemdetail_error)
and fdetailid not in (select fdetailid_temp from t_itemdetail_error)
(10)更新纵表:
exec sp_cleanitemdetailv
(11)更正凭证分录数据:
update a set a.fdetailid=b.fdetailid_temp
from t_voucherentry a join t_itemdetail_error b on a.fdetailid=b.fdetailid
where a.fdetailid<>b.fdetailid_temp
总结
一般的处理 Fdetailid 相关信息的逻辑顺序为:
1、查询被科目使用的核算项目使用详情信息
2、查询、更正核算项目使用详情组合个数
3、根据实际情况,更正科目表(或凭证表,余额表)中的 Fdetailid 和删除 t_itemdetail
表中的重复记录
4、补充检查出来的账套中预设的 0 记录(一般情况下不会有)
5、反结账到到出现问题的期间,建议同时将反结账后期间的凭证反过账;
6、删除三个余额表中的错误 Fdetailid 记录
7、如果结转损益的凭证数据有误,建议删除
8、更正和补充其他相关数据(如补充 t_itemdetail 表中丢失的列等)
9、数据修正完后,凭证重新过账,重新结转损益过账,再结账到当前期间。