<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Wrong sheet names in libname xlsx in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Wrong-sheet-names-in-libname-xlsx/m-p/794192#M254634</link>
    <description>&lt;P&gt;I am not allowed to download files, so i created one and got the same error message you have posted.&lt;/P&gt;
&lt;P&gt;So please contact sas tech support, this seems to be a bug.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;SAS: 9.04.01M7&lt;/P&gt;</description>
    <pubDate>Thu, 03 Feb 2022 11:26:17 GMT</pubDate>
    <dc:creator>andreas_lds</dc:creator>
    <dc:date>2022-02-03T11:26:17Z</dc:date>
    <item>
      <title>Wrong sheet names in libname xlsx</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Wrong-sheet-names-in-libname-xlsx/m-p/794185#M254629</link>
      <description>&lt;P&gt;I have/had a problem concerning the import of excel files, for which I don't know the sheet names. So I usually proceed by&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;getting a dataset with all the sheet names for that file and&lt;/LI&gt;&lt;LI&gt;run an import macro (the specifics don't matter here) via call execute on that dataset.&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;Part a. is done as follows&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;%let file = path_to_file;
libname xlsxtmp xlsx "&amp;amp;file.";

proc contents data=xlsxtmp._all_ out=work.sheets noprint;
run;

data work.sheets;
  set work.sheets;
  by memname;
  if first.memname then do;
    sheet = memname;
    output;
  end;
  keep sheet;
run;

libname xlsxtmp clear;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;The excel files I have to import come from a lot of different sources and I recently got an error&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;P&gt;ERROR: Couldn't find sheet in spreadsheet.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;in the Proc Contents.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This was due to a sheet with a trailing blank in the sheet name (yes, Excel allows that). I attached a file for demonstration. The xlsx-Engine just strips this trailing blank. Since I use SAS EG, I just tried the&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;libname xlsxtmp xlsx "&amp;amp;file.";&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;by itself. All sheets are shown in die library.&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Clicking on the one with the trailing blank in the name ("sheet with trailing blank") to open it in EG results in an error.&lt;/LI&gt;&lt;LI&gt;Copying the sheet with a datastep fails using the correct sheet name (without the trailing blank it fails, too)&lt;PRE&gt;&lt;CODE class=""&gt;set xlsxtmp.'sheet with trailing blank 'n;&lt;/CODE&gt;&lt;/PRE&gt;&lt;/LI&gt;&lt;LI&gt;Proc import on that file works, when sheet is set to the correct name with the trailing blank (without it if fails)&lt;BR /&gt;&lt;PRE&gt;&lt;CODE class=""&gt;proc import file="&amp;amp;file." dbms=xlsx out=work.import replace;
  sheet="sheet with trailing blank ";
run;&lt;/CODE&gt;&lt;/PRE&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;SAS version 9.04.01M4&lt;/P&gt;&lt;P&gt;EG version 7.13HF5&lt;/P&gt;</description>
      <pubDate>Thu, 03 Feb 2022 11:02:36 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Wrong-sheet-names-in-libname-xlsx/m-p/794185#M254629</guid>
      <dc:creator>msauer</dc:creator>
      <dc:date>2022-02-03T11:02:36Z</dc:date>
    </item>
    <item>
      <title>Re: Wrong sheet names in libname xlsx</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Wrong-sheet-names-in-libname-xlsx/m-p/794189#M254632</link>
      <description>&lt;P&gt;Sounds like you've done a thorough round of testing.&amp;nbsp; I would suggest sending this in to tech support. to see if they confirm or have a fix.&lt;/P&gt;</description>
      <pubDate>Thu, 03 Feb 2022 11:15:37 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Wrong-sheet-names-in-libname-xlsx/m-p/794189#M254632</guid>
      <dc:creator>Quentin</dc:creator>
      <dc:date>2022-02-03T11:15:37Z</dc:date>
    </item>
    <item>
      <title>Re: Wrong sheet names in libname xlsx</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Wrong-sheet-names-in-libname-xlsx/m-p/794190#M254633</link>
      <description>&lt;P&gt;I also tried everything I could imagine, with no success. Even this fails:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc copy in=xlsxtmp out=work;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;where SAS should automatically use the names as it finds them.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Bottom line: remove the blank in Excel before import.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Final bottom line: another illustration why Excel files&amp;nbsp;&lt;STRONG&gt;MUST NOT BE USED FOR DATA TRANSFER&lt;/STRONG&gt;.&lt;/P&gt;</description>
      <pubDate>Thu, 03 Feb 2022 11:16:05 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Wrong-sheet-names-in-libname-xlsx/m-p/794190#M254633</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2022-02-03T11:16:05Z</dc:date>
    </item>
    <item>
      <title>Re: Wrong sheet names in libname xlsx</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Wrong-sheet-names-in-libname-xlsx/m-p/794192#M254634</link>
      <description>&lt;P&gt;I am not allowed to download files, so i created one and got the same error message you have posted.&lt;/P&gt;
&lt;P&gt;So please contact sas tech support, this seems to be a bug.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;SAS: 9.04.01M7&lt;/P&gt;</description>
      <pubDate>Thu, 03 Feb 2022 11:26:17 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Wrong-sheet-names-in-libname-xlsx/m-p/794192#M254634</guid>
      <dc:creator>andreas_lds</dc:creator>
      <dc:date>2022-02-03T11:26:17Z</dc:date>
    </item>
    <item>
      <title>Re: Wrong sheet names in libname xlsx</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Wrong-sheet-names-in-libname-xlsx/m-p/794193#M254635</link>
      <description>&lt;P&gt;I have a workaround using the excel engine instead of xlsx. This produces different sheet names that are also not "bulletproof".&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;libname xlsxtmp excel "&amp;amp;file.";&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;Using Proc Contents on this library fails, when one of the sheets has a single quote in the name. It's the same in the EG, that clicking on this sheet results in an error. The reason for this is that single quotes are masked by two single quotes, i. e.&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;sheet'1 &amp;gt;&amp;gt;&amp;gt; sheet''1&lt;/PRE&gt;&lt;P&gt;Fortunately, this is easier to work around than a missing trailing blank.&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Retrieve list of sheets with Proc Datasets&lt;BR /&gt;&lt;PRE&gt;&lt;CODE class=""&gt;ods output members=work.sheets;
proc datasets lib=xlsxtmp memtype=data;
quit;&lt;/CODE&gt;&lt;/PRE&gt;&lt;/LI&gt;&lt;LI&gt;Sheet names with non-alphanumeric characters(except a single quote) are enclosed in single quotes. In order to have a consistent behaviour just quote those which aren't already quoted.&lt;/LI&gt;&lt;LI&gt;Remove the trailing $-sign.&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;In subsequent processing you have to be careful about the single and double quotes. For instance, I use Proc Import with the Range option&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;proc import file="&amp;amp;file." dbms=xlsx out=work.import;
  getnames=no;
  range="%bquote(&amp;amp;sheet.)$&amp;amp;start.:&amp;amp;end.";
run;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;For this to work, you have to replace&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;two single quotes by one single quote and&lt;/LI&gt;&lt;LI&gt;one double quote by two double quotes&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;in the sheet name.&lt;/P&gt;</description>
      <pubDate>Thu, 03 Feb 2022 11:26:42 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Wrong-sheet-names-in-libname-xlsx/m-p/794193#M254635</guid>
      <dc:creator>msauer</dc:creator>
      <dc:date>2022-02-03T11:26:42Z</dc:date>
    </item>
    <item>
      <title>Re: Wrong sheet names in libname xlsx</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Wrong-sheet-names-in-libname-xlsx/m-p/794304#M254690</link>
      <description>&lt;P&gt;Did you try setting Option Validmemname=Extend; ?&lt;/P&gt;
&lt;P&gt;Not stated explicitly so thought it might be worth checking.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 03 Feb 2022 17:43:03 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Wrong-sheet-names-in-libname-xlsx/m-p/794304#M254690</guid>
      <dc:creator>ballardw</dc:creator>
      <dc:date>2022-02-03T17:43:03Z</dc:date>
    </item>
    <item>
      <title>Re: Wrong sheet names in libname xlsx</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Wrong-sheet-names-in-libname-xlsx/m-p/794311#M254693</link>
      <description>I did not set this explicitly but the behaviour does not change. Maybe this option is already set implicitly with the libname statement, seeing that the names of datasets (=sheets) contain blanks and special characters.</description>
      <pubDate>Thu, 03 Feb 2022 17:56:15 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Wrong-sheet-names-in-libname-xlsx/m-p/794311#M254693</guid>
      <dc:creator>msauer</dc:creator>
      <dc:date>2022-02-03T17:56:15Z</dc:date>
    </item>
    <item>
      <title>Re: Wrong sheet names in libname xlsx</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Wrong-sheet-names-in-libname-xlsx/m-p/795628#M255227</link>
      <description>&lt;P&gt;Further testing revealed additional problems with the excel-engine.&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Dots (.) are replaced by #.&lt;/LI&gt;&lt;LI&gt;! are replaced by _.&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;So the best solution I have found thus far is the following:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;extract sheet names with both engines,&lt;/LI&gt;&lt;LI&gt;normalize the sheet names such that the two datasets can be merged,&lt;/LI&gt;&lt;LI&gt;add the leading and trailing spaces to the names provided by the xlsx engine.&lt;/LI&gt;&lt;/UL&gt;&lt;PRE&gt;&lt;CODE class=""&gt;/* Get sheet names via xlsx. */
libname tmp xlsx "&amp;amp;file.";
ods output members=work.xlsx;
proc datasets lib=tmp memtype=data;
run;
libname tmp clear;

/* Get sheet names via excel. */
libname tmp excel "&amp;amp;file.";
ods output members=work.excel;
proc datasets lib=tmp memtype=data;
run;
libname tmp clear;

/* Normalize sheet names for merge. */
data work.xlsx;
  set work.xlsx;&lt;BR /&gt;  length sheet $ 50 sheet_merge $ 50;
  sheet = name;
  sheet_merge = upcase(tranwrd(tranwrd(name, ".", "#"), "!", "_");&lt;BR /&gt;  keep sheet sheet_merge;
run;

data work.excel;
  set work.excel;&lt;BR /&gt;  length sheet_merge $ 50 leading_spaces 3 trailing_spaces 3;
  if substr(name, length(name), 1) = "$" then
    /* Trailing $ when no space in sheet name. */
    do;
      sheet_merge = upcase(strip(substr(name, 1, length(name) - 1)));
      leading_spaces = 0;
      trailing_spaces = 0;
    end;
  else if substr(name, length(name) - 1, 2) = "$'" then
    /* If spaces in sheet name, then sheet name is enclosed by single quotes. */
    do;
      sheet_merge = upcase(strip(substr(name, 2, length(name) - 3)));
      /* Single quotes have been doubled. */
      sheet_merge = tranwrd(sheet_merge, "''", "'");
      leading_spaces = length(substr(name, 2)) - length(strip(substr(name, 2)));
      trailing_spaces = lengthc(substr(name, 1, length(name) - 2)) - lengthc(strip(substr(name, 1, length(name) - 2)));
    end;
  /* Named ranges are included without trailing $. Omit them. */
  if not missing(sheet_merge) then
    output;&lt;BR /&gt;  keep sheet_merge leading_spaces trailing_spaces;&lt;BR /&gt;run;

proc sort data=work.xslx;
  by sheet_merge;
run;
proc sort data=work.excel;
  by sheet_merge;
run;

data work.sheets;
  merge work.xlsx work.excel;
  by sheet_merge;
  /* Enclose name with [] (not allowed by Excel). */
  sheet = cats("[", sheet, "]");
  /* Add the spaces. */
  do i = 1 to leading_spaces;
    sheet = tranwrd(sheet, "[", "[ ");
  end;
  do i = 1 to trailing_spaces;
    sheet = tranwrd(sheet, "]", " ]");
  end;
  /* Enclose with single quotes and escape single quotes in the sheet name. */
  sheet = tranwrd(sheet, "'", "''");
  sheet = tranwrd(sheet, "[", "'");
  sheet = tranwrd(sheet, "]", "'");
  keep sheet;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Fri, 11 Feb 2022 11:34:52 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Wrong-sheet-names-in-libname-xlsx/m-p/795628#M255227</guid>
      <dc:creator>msauer</dc:creator>
      <dc:date>2022-02-11T11:34:52Z</dc:date>
    </item>
  </channel>
</rss>

