亲爱的 JMP 社区:
我的任务是编写一个脚本,旨在自动从“混乱”的 Excel 文件中导入数据。 我说“混乱”是因为我想要从 Excel 文件中提取的实际数据没有以整齐的列和行的形式组织 - 它遍布各处 - 但它始终位于每个 Excel 文件中的相同位置。 这些文件基本上包含我们生产批次的批次信息,我正在尝试从这些 Excel 文件中提取测试数据并将其放入 JMP 数据表中。
有多个批次 Excel 文件分布在多个目录中。 为了解决这个问题,我使用 Files In Directory() 命令生成需要打开的所有 Excel 文件的列表,并带有“递归”标志,因此在构建列表时我还会获取所有子目录。 这将创建一个长达数百项的列表。 将该列表命名为 NLotFiles。
我首先有一个从 i=1 到 N Items(NLotFiles) 长的 For 循环,因此它需要通过这个更大的 For 循环运行几百次。
然后,我需要多次打开该文件并每次导入一些信息。 我需要多次执行此操作,因为信息不仅分布在多个单元格中,而且还分布在 Excel 文件中的多个选项卡中。
第一次打开会提取日期和批次信息。 然后我需要检查第一列第一行中是否有条目(如果存在日期)。 如果没有,我想关闭该数据表并返回到第一个 For 循环,进入下一次迭代。
****这就是我陷入困境的地方。
接下来的多次打开将所有数据拉出到其他表中,然后将它们连接在一起并形成一个大数据表。 只要每个文件中都有日期条目,此方法就有效。 但是,并非所有文件都有日期——例如,当天没有进行任何批次。 如果发生这种情况,它仍然会打开该文件,但所有其余代码都无法正常工作,因为它基于 Excel 文件的结构和日期的存在。
由于 JSL 中没有 GOTO 选项,因此我很难测试日期值并关闭表(如果没有)并返回到 NLotFiles 列表中的下一个迭代。 我正在使用 Is Missing() 函数测试日期是否存在,并尝试使用Continue(),但它没有像我想象的那样工作。
这段代码的基本结构是这样的:
For( i= 1, i<=N Items( NLotFiles ), i++,
Open(
DataPath || "\"|| DataFiles[i],
Worksheets( "Coversheet" ),
Use for all sheets( 1 ),
Concatenate Worksheets( 0 ),
Create Concatenation Column( 0 ),
Worksheet Settings(
1,
Has Column Headers( 1 ),
Number of Rows in Headers( 1 ),
Headers Start on Row( 2 ),
Data Starts on Row( 3 ),
Data Starts on Column( 3 ),
Data Ends on Row( 3 ),
Data Ends on Column( 5 ),
Replicated Spanned Rows( 1 ),
Replicated Spanned Headers( 0 ),
Suppress Hidden Rows( 1 ),
Suppress Hidden Columns( 1 ),
Suppress Empty Columns( 1 ),
Import Cell Colors( 0 ),
Limit Column Detect( 0 ),
Column Separator String( "-" )
)
);
//This part tests if the date (first column, first row) is empty.
If(Is Missing(Column(Current Data Table(),1)[1])==1,
Close(Current Data Table(), no save),
Continue()
);
/////*****HERE IS WHERE I WANT IT TO GO BACK TO THE TOP IF NO DATE IS PRESENT BUT CONTINUE DOWN BELOW IF A DATE IS PRESENT*****
/////I don't think the Continue() is in the right place, but then if I don't have it present, the code just stops because all the stuff below can't be done.<BR /><BR /><BR />//This part ensures the date is Numeric and Continuous
datedt = Current Data Table();
datedt:Date << Data Type( Numeric, Format( "m/d/y" ) ) << Modeling Type( "Continuous" );
//Next steps would bring in the data from different tabs as the date information (again, I have to do multiple opens on the same file.)
//Then join all the data, clean things up in the new data tables<BR /><BR />); //This last ");" closes the big For loop that runs through a total of NLotFiles times.<BR /><BR />//Then I concatenate the multiple tables (each table represents a lot now) into my final data table and close all unwanted tables.如果我能够告诉 JMP 要导入哪些确切的选项卡和单元格(例如使用选项卡和单元格编号列表,因为这些选项卡和单元格编号在 Excel 文件中始终相同),那就太好了。 这将消除引入所有内容所需的多重循环。
非常感谢任何帮助,特别是如果有人更好地了解如何提取重要信息并使代码比当前更容易/更简单。 我的实际代码总共大约有 300 行(包括空行),所以还不错。 但更简单的代码通常更容易排除故障,也更容易让其他人编写代码。
谢谢!,
DS
你好@gzmorgan0 ,
感谢您的反馈意见。 我想我已经尝试过了,但仍然没有成功。 问题不在于“粘合剂”,而在于退出“If(Is Missing...”部分后,大的外部 For 循环继续,并且不知道在代码的后续部分要做什么,因为数据表本来打开的已经不存在了。
我昨天刚刚找到了一个解决方法,今天早上测试过,效果非常好。 它的运行完全像我想象的那样。
我发现如果我将“禁止空列(1)”(这是打开 Excel 文件时的默认设置)更改为“禁止空列(0)”,它将打开一个空数据表,我可以在其中将日期设置为1/1/1904(即0),然后,在我从数百个文件构建大数据表后,我搜索了所有date=0的行并删除了它们。
它可能不是最优雅的解决方案,但由于 JSL 没有任何 GoTo 选项,这是我能做的最好的解决方案——至少是我能够做的。 因此,它会生成一堆空条目,但这些条目很容易搜索,而不是在 for 循环中关闭表。
谢谢!,
DS
@SDF1 ,
我还没有彻底消化您所描述的问题,但是,我在您的代码中发现了错误,这可能会为您带来一些进展。
您的 JSL:
//This part tests if the date (first column, first row) is empty.
If(Is Missing(Column(Current Data Table(),1)[1])==1,
Close(Current Data Table(), no save),
Continue()
);
错误是关闭后的逗号。 我认为您想关闭并继续。 逗号应该是分号。 分号是您想要执行的每个 JSL 命令/操作的粘合剂,即它定义了要执行的代码块。
将其替换为此内容,您的Continue()应该可以工作:
//This part tests if the date (first column, first row) is empty.
If(Is Missing(Column(Current Data Table(),1)[1])==1,
Close(Current Data Table(), no save);
Continue()
);