SAS 9.4 64位XLSX 32位导入:日期和文本以文本形式读入的列,格式为无格式

问题描述:

我正在使用64位SAS 9.4从32位Excel导入文件。我的许多Excel列包含日期的两个日期和列表,像这样:SAS 9.4 64位XLSX 32位导入:日期和文本以文本形式读入的列,格式为无格式

SeptemberDatesCol
9/13 & 9/27
9/13 9/26 &
9/01 9/10 & & 9/21
9/23
9/30
9/30
9/28

我不是文件的所有者,并更新[R所以所有主要的操作和格式化都需要在SAS中进行。导入后,我可以将其更改为每行一个日期的正常列表,但导入本身并未正确导入日期。我的导入代码:

PROC IMPORT OUT=Raw_Import DATAFILE= "J:\filename.xlsx" DBMS=XLSX REPLACE; 
SHEET="Sheetname"; 
GETNAMES=YES;  
RUN; 

SeptemberDatesCol进口作为一个字符变量(如需要),但对于有一个日期行的一些,日期是进口与Excel的原始未格式化的日期约定值:

SeptemberDatesCol
9/13 & 9/27
9/13 9/26 &
9/01 9/10 & & 9/21
9/23

我能做些什么不同,以获得柱正确导入?当我使用DBMS = EXCELCS时,我获得'无法连接到服务器'的错误。 DBMS = EXCEL在我工作的软件设置(32位Excel的64位SAS 9.4)下不起作用。提前感谢您提供的任何建议。

当您在具有混合文本和数字的XLSX文件中导入列时,SAS将以原始格式导入数字。通过使用简单的算术,您可以将看起来像原始日期的字符串从Excel的基准日期转换为SAS的基准日期。因此,如果您减去两个系统使用的基准日期之间的差异,并且还要减去一个,因为SAS从0开始计数,而Excel从1开始计数,同时也减去1,因为Excel认为1900是闰年。

sasdt = exceldt - ('01JAN1960'd - '01JAN1900'd +2) ; 

但由于“01JAN1960'd就是零,你可以简化为

sasdt = exceldt + '01JAN1900'd - 2 ; 

现在你只需要一点点逻辑告诉数字和字符串之间的区别。例如,您可以测试字符串是否转换为1('01JAN1900'd)和43,100('31DEC2017'd)之间的数字,如果它将其转换为MM/DD/YYYY格式的字符串。

if 0 <= input(SeptemberDatesCol,??32.) <= 43100 then 
    SeptemberDatesCol = put(input(SeptemberDatesCol,??32.),mmddyys10.) 
; 

所以你的例子数据将得到改造成:

52 data have ; 
53  input SeptemberDatesCol $30. ; 
54  put SeptemberDatesCol= @ ; 
55  if 0 <= input(SeptemberDatesCol,??32.) <= 43100 then 
56   SeptemberDatesCol = put(input(SeptemberDatesCol,??32.)+'01JAN1900'd-2,mmddyys10.) 
57  ; 
58  put '-> ' SeptemberDatesCol ; 
59 
60 cards; 

SeptemberDatesCol=9/13 & 9/27 -> 9/13 & 9/27 
SeptemberDatesCol=9/13 & 9/26 -> 9/13 & 9/26 
SeptemberDatesCol=9/01 & 9/10 & 9/21 -> 9/01 & 9/10 & 9/21 
SeptemberDatesCol=9/23 -> 9/23 
SeptemberDatesCol=42643 -> 09/30/2016 
SeptemberDatesCol=42643 -> 09/30/2016 
SeptemberDatesCol=42641 -> 09/28/2016