【问题标题】:Replacing table values with txt file VFP用 txt 文件 VFP 替换表值
【发布时间】:2016-05-23 11:16:28
【问题描述】:

我试图用 txtfile 中的信息替换 phc 表,但我没有在屏幕上获取信息。

re 是我要替换值的表 txtcabecalho 是人们必须选择的导入文件 reciboc 是我创建的用于存储 txt 文件中的值的光标,因此我可以在 re 上替换它们并将它们显示到屏幕上 sre 是表 re 的屏幕。

    Local txtcabecalho
Use re
Delete all
txtcabecalho=getfile("txt")

Create cursor reciboc(rno n(10), rdata d(10), moeda c(3), no n(10), nome c(2), ccusto c(20), intid c(10), clbanco c(20), total float(19), totalmoeda float(19), ndoc n(3))


append from (txtcabecalho) delimited with tab
select reciboc
goto top
scan for !empty(reciboc.rno)

select re
append blank
replace re.rno with reciboc.rno 
replace re.rdata with reciboc.rdata
replace re.moeda with reciboc.moeda
replace re.no with reciboc.no
replace re.nome with reciboc.nome
replace re.ccusto with reciboc.ccusto
replace re.intid with reciboc.intid
replace re.clbanco with reciboc.clbanco
replace re.total with reciboc.total 
replace re.totalmoeda with reciboc.totalmoeda 
replace re.ndoc with reciboc.ndoc
select re
endscan

sre.refresh()

谢谢!

更新

因此,如果我使用我选择的分隔符(例如使用制表符)创建我自己的文件,这实际上是有效的。这件事是我需要导入的文件就像使用空格作为空间持有者并且彼此没有分隔符。让我解释得更好。例如前 3 个字段 rno 和 rdata 和 moeda。

txt 文件类似于22014-12-23EUR

其中 2 是 rno,但后面有 9 个空格,就像占位符一样,用于更大的数字,使 rno(10) 接下来是 2014-12-23,它就在 rno 旁边,没有 rdata(10) 的定界 接下来是欧元的moeda,同样没有定界,是moeda(3)

许多字段将是空白的,并且那些 txt 文件带有占据整个字段长度的空格。基本上,字段长度用作分隔符,当为空时,它用空格填充。

你没听错吧?对不起,我不是英语母语。

更新

这里是一些txt文件22014-11-27EUR 208 799,00 799,00 00

请记住,在第一个数字 2 之前,有 9 个空格。 谢谢!

将用 2014-11-27 填充的 rdata 字段是 rdata d(10)

已编辑

当前代码:

Local txtcabecalho, fileconvert
Use re
zap
txtcabecalho=getfile("txt")
Create cursor reciboc(rno n(10), rdata d(10), moeda c(3), no n(10), nome c(2), ccusto c(20), intid c(10), gg c(20), chq c(20), clbanco c(20), total float(19), totalmoeda float(19), ndoc n(3))

fileconvert = filetostr(txtcabecalho)
chrtran(fileconvert,'-','')
strtofile(fileconvert, txtcabecalho)

append from (txtcabecalho) type sdf
scan 
select re
append blank
replace rno with reciboc.rno 
replace rdata with reciboc.rdata
replace moeda with reciboc.moeda
replace no with reciboc.no
replace nome with reciboc.nome
replace ccusto with reciboc.ccusto
replace intid with reciboc.intid
replace clbanco with reciboc.clbanco
replace total with reciboc.total 
replace totalmoeda with reciboc.totalmoeda 
replace ndoc with reciboc.ndoc
select re

endscan
select reciboc
browse title "resultado"

reindex
sre.refresh()

我得到的是this is what i get

还在想办法,我真的不知道啊

例如:第一行应该是:

RNO 2 RDATA 2014-11-27 NO 208

已编辑

其实这样就成功了啊

fileconvert = filetostr(txtcabecalho)
fileconvert2 = strtran(fileconvert,'-','')
strtofile(fileconvert2, txtcabecalho)

如果我需要进一步的帮助,我会更新我的问题!非常感谢你们!

已编辑

你们知道从txt文件浮点数转换成游标有什么问题吗?

例如,我得到了 799,20,但我只是显示为 799。数据类型设置为 totalmoeda f(19) 。这一定很简单,但我找不到!

【问题讨论】:

  • 附带说明,当您需要发出多个替换命令时,不要发出单独的替换命令,而是发出一个。您可以像这样用一个替换多个替换:将 f1 替换为 'f1content',将 f2 替换为 'f2Content' ... 这样就可以通过一次替换进行替换。您的每次更换都会进行更换。在这里并不重要,但请记住,这会极大地影响性能(而且 VFP 开发人员对性能很疯狂)。
  • float 类型与 numeric 类型相同。如果需要小数,则必须将它们包含在列的定义中。无论数据类型如何,F(19) 都是整数。
  • 我想办法做到这一点,但我不明白我应该如何做到这一点

标签: visual-foxpro foxpro dbase xbase


【解决方案1】:

您正在执行一个 SCAN 循环,这意味着来自 reciboc 表的许多行。但是,在您的“重新”表中,您只需使用相同的值覆盖同一行,如果文件中没有记录,您将一无所有。如果要添加它们,则需要附加到“RE”表中。

现在,另一个考虑因素是“rno”列。是否应该是“ID”列,例如您的外部文本文件可能已更新每个给定“RNO”的值,如果它尚不存在,您想要更新,或者如果它不存在于“re”中则添加桌子?

使用标签和额外澄清的元素更新您的问题...

如果您在“RNO”列的“RE”表上有索引,那就太好了。如果不是,那是您要更新的关键列,我建议在其上创建一个索引...

从 VFP 命令窗口构建索引,使其始终可用

use RE exclusive
index on RNO tag RNO
use

现在,在您的代码中,在您从定界处追加后,您的光标已准备好...我将在实时表和您的临时光标之间设置一个关系,并像这样进行更新...

选择瑞波克 RNO 标签上的索引 RNO && 所以游标也有索引。

选择 RE 将与 RNO 的关系设置为 RECIBOC

现在,对于每个表中匹配的任何记录,这两个表都相互指向。现在,替换 FOR [范围]。由于关系的原因,由于“RE”表中的记录是循环的,如果存在,它将指向“RECIBOC”表中相同的RNO记录。所以 FOR 条件是测试 NOT EOF() (文件结尾 = 在 RECIBOC 中找不到匹配项。所以 NOT EOF() 表示找到了一条记录。

replace rdata with reciboc.rdata,;
        moeda with reciboc.moeda,;
        no with reciboc.no,;
        nome with reciboc.nome,;
        ccusto with reciboc.ccusto,;
        intid with reciboc.intid,;
        clbanco with reciboc.clbanco,;
        total with reciboc.total,;
        totalmoeda with reciboc.totalmoeda,;
        ndoc with reciboc.ndoc ;
   FOR NOT EOF( "RECIBOC" )

最后,将任何新的“RNO”记录放入“RE”表中。根据匹配的“RNO”列获取不在现有 RE 表中的所有记录。

select * ;
   from RECIBOC ;
   WHERE RNO NOT IN ( select RNO from RE );
   into cursor NewRecordsToAdd readwrite

现在,将它们添加到“RE”表中。由于这些列是相同的名称,它们将直接从/到引用而没有明确的列名。

select RE
append from dbf( "NewRecordsToAd" )
use in select( "NewRecordsToAdd" )   

【讨论】:

  • @joh,刚刚修改了答案。此外,为了将来,您可以编辑原始问题,而不是发布答案。您可以将 cmets 添加到某人的帖子中,以便他们看到您的回复。还请查看顶部菜单“帮助 -> 游览”以了解网站礼仪。
  • 感谢您的所有帮助,但我是一个非常基本的 vfp 程序员,我没有得到您所获得的信息的一半。我认为我正在使用 VFP、xBase 和 Clipper 的混合体,我用它来定制一些 PHC 操作,PHC 是一个 ERP。我想我不能让你确定我想做什么。基本上我想浏览一个 txt 文件,并用 txt 文件具有的信息替换屏幕中的字段。合成器与原始 VFP 不完全相同,但我可以理解。我的主要问题是将 TXT 文件数据分别放入 CURSOR 字段。谢谢
【解决方案2】:
Create Cursor reciboc(rno N(10), rdata d(10), moeda c(3), no N(10), ;
    Nome c(2), ccusto c(20), intid c(10), clbanco c(20), ;
    Total Float(19), totalmoeda Float(19), ndoc N(3))

Append From (m.txtcabecalho) Type Delimited With Blank

Select re
Append from (Dbf('reciboc'))

以上是您尝试做的简短版本。

【讨论】:

    【解决方案3】:

    在您的更新中,您所描述的是固定宽度数据格式或所谓的系统数据格式 (SDF)。然后不要使用 delimited 而是 SDF 作为类型:

    Create Cursor reciboc(rno C(10), rdata C(10), moeda c(3), no C(10), ;
        Nome c(2), ccusto c(20), intid c(10), clbanco c(20), ;
        Total C(19), totalmoeda C(19), ndoc C(3))
    
    Append From (m.txtcabecalho) Type SDF
    
    alter table reciboc alter column rdata d && convert rdata column to date
    * do other needed column type conversions
    
    Select re
    Append from (Dbf('reciboc'))
    

    创建光标时使用的大小应与文本文件中数据列的大小相匹配。将整个数据作为文本获取后,更改列以匹配数据类型(我假设您的大小是正确的) - d(10) 没有意义,并且 float 从来都不是建议的类型。

    PS:如果你能找到 FoxyClasses,那么它里面确实有一个导入器类,它可以为你处理大部分工作(不幸的是,我丢失了用于下载的服务器)。如果可以找到,您可以阅读其 chm 文件中的详细信息。

    【讨论】:

    • 非常感谢你,正如我所说,我喜欢这门语言 2 天,我还有很多东西要学。一件事。 re 表的格式是 dd-mm-yyyy 但文件格式是 yyyy-mm-dd ,你们知道如何应对吗?如果我不改变这一切都会变得一团糟啊哈。它来自两者的 rdata 字段
    • 无论文本文件中的格式如何,然后将您的日期格式设置为匹配。即:如果在文本文件中它是 yyyy-mm-dd 那么:“设置日期 YMD”如果它是 dd-mm-yyyy 然后“设置日期 DMY”。在执行更改表之前在任何地方发出此命令。此外,如果日期格式不是标准的,那么您也可以使用函数来操作数据(但现在这对您来说是高级的)。
    • 我认为有一些冲突 - - 我遇到了同样的问题。按照我给出的示例,而不是显示 EUR 显示在 28E 中,其中 28 是日期的一部分,并且在日期上什么也不显示。所以我觉得 3 个字符有问题,可能是 - - - 。生病继续努力,看看是否能得到解决方案。谢谢!
    • 你为什么不从你的文本文件中给我们几行? (如果您可以编辑您的问题并按原样添加行,那就太好了)。
    • 我不认为 stackoverflow 检测到空格。但这里是:22014-11-27EUR 208 799,00 799,00 00 日期是冲突的,因为在应该显示 EUR 的位置上显示 27E。
    【解决方案4】:

    在 2 之前正好有 9 个空格,这对我有用:

    Create Cursor reciboc(rno C(10), rdata C(10), moeda c(3), no C(10), ;
        Nome c(2), ccusto c(20), intid c(10), clbanco c(20), ;
        Total C(19), totalmoeda C(19), ndoc C(3))
    
    Append From (m.txtcabecalho) Type SDF
    browse title "Before data type change"
    
    Set Date YMD
    Set Century ON
    
    alter table reciboc alter column rdata d && convert rdata column to date
    browse title "After date type change"
    

    如果是 SDF,请记住文本文件中指定字段宽度的位置。

    【讨论】:

    • 我仍然有同样的问题,我无法弄清楚。我光标中的 rdata 字段的宽度为 10。但是,如果我取出文本文件的“-”“-”,一切都会正常工作,即使它在保持 8 宽度之后也是如此。更改表格或文本文件不是一种选择。我假设表 re 中的 rdata 字段上已经有两个“-”填充了 2 个空格,只剩下 8 个,这就是它适合的原因。你怎么看?我不知道如何将数据放入 rdata 使其忽略 txt 文件中的“-”。谢谢你们的帮助
    • 有 chrtran() 和 strtran() 函数,但我不明白你的意思。尝试用 chrtran(rdata,'-','') all 替换 rdata - 在 alter table 命令之前在 reciboc 上。它只适用于 - 对我来说。
    • 检查设定点。或者,您可以用适当的小数点分隔符替换逗号。
    猜你喜欢
    • 1970-01-01
    • 2016-04-20
    • 1970-01-01
    • 2022-10-03
    • 2011-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多