Hello everyone.
I am using SAS® Customer Intelligence Studio to create CRM campaigns.
I want to execute campaign with Serbian special characters in it (šđžčć) and to export client data with special characters to excel file.
Can someone please help me how to do this?
Thank you everyone for your help!
Hi
I actually had a similar problem but with Nordic characters through a DM task. This happens if the encoding of the SAS platform is different than UTF-8 so the process fails at that point. To fix it, the options are either to change the encoding of the SAS platform or to change the encoding of the maexp.sas file in the direct marketing agent to add some code to cater for these changes. This will also mean that when the agent is updated, there needs to be a check that the maexp.sas file is still valid.
This presents the lowest risk. However, it involves changing one of the files of the DM agent which need then to be reconciled with the new version every time there is a DM agent version release (almost every month). So, when the DM agent update is upgraded, a SAS admin on the platform needs to compare the maexpfil.sas file against the new version that comes in the agent upgrade and if there are differences, implement them while still keeping the encoding changes.This can be an automated process as well but still needs an approval if the change should take place or not.
Steps to follow to change the file:
/*****************************************************************/ /* Copyright (c) 2007 - 2013 by SAS Institute Inc., Cary, NC, */ /* USA. */ /* All Rights Reserved. */ /* This software is protected by copyright laws and */ /* international treaties */ /* */ /* U.S. Government Restricted Rights */ /* Use, duplication, or disclosure of this software and related */ /* documentation by the U.S. government is subject to the */ /* Agreement with SAS Institute and the restrictions set forth */ /* in FAR 52.227-19, Commercial Computer Software - */ /* Restricted Rights ( June 1987 ) */ /* */ /*****************************************************************/ /* NAME: maexp */ /* VERSION: 6.1 */ /*****************************************************************************/ /* PRISM VERSION: $Revision: 1.5.2.7.2.6.2.4.4.1.2.7.4.6.2.1.6.3.2.9.4.3 $ ; /* Revision Date: $Date: 2017/08/08 13:20:07 $ ; /*****************************************************************************/ /*****************************************************************************/ /* HISTORY: */ /* DATE Defect No Comments/updated by */ /* --------- --------- --------------------------------------------------- */ /* 23APR2013 GA */ /*****************************************************************************/ /* class: export */ %macro maexpfil( input, vards, varList, output, outputType, headerRow, appendReplace, override , quoteRule); %if &MADebug = Y %then %do; %put Input table: &input; %put Variable data set: &vards; %put Variable list: &varList; %put Output name: &output; %put Output type: &outputType (7=Delimited, 4=Positional); %put Header row: &headerRow; %put Append or replace: &appendReplace; %put Override delimiter: &override; %put Quote Rule: "eRule; %end; %*-----get filename and delimter for export file-----*; /* S0897280 - removed checks for outputtype= 0 & 1 */ %if %quote(&override) eq 'export_delimiter_comma' %then %let dlmchar=%str(","); %else %if %quote(&override) eq 'export_delimiter_tab' %then %let dlmchar='09'x; %else %if %quote(&override) eq 'export_delimiter_semicolon' %then %let dlmchar=%str(";"); %else %let dlmchar=%str(&override); %if &headerRow=Y and %upcase(&appendReplace) = APPEND and %sysfunc(fileexist(&output)) %then %let headerRow=N; %* do not add header if appending to file that already exists.; %* determine file statement for file based exports; %let export_filestmt=; %let export_filestmt=file "&output"; %if %upcase(&appendReplace) = APPEND %then %let export_filestmt=&export_filestmt mod; /* S0897280 - removed checks for outputtype= 0 & 1 */ %if &outputType=7 %then %let export_filestmt=&export_filestmt dlmstr=&dlmchar; /*Delimited or (old) CSV or TAB delimited*/; %let export_filestmt=&export_filestmt recfm=v lrecl=32767; /*******************************************/ /* START SECTION "Identify email export". */ /*******************************************/ /* This section ensures that on-prem email exports are generated in UTF-8 */ data _null_; path = strip(symget("OUTPUT")); f = scan(path, -1, "/\"); if index(f, "EmailExport_") = 1 then do; call symputx("IS_EMAIL_EXPORT", "YES"); putlog "**************************"; putlog path "is an email export"; putlog "IS_EMAIL_EXPORT=YES"; putlog "Sets output encoding to UTF-8"; putlog "*************************"; end; else do; call symputx("IS_EMAIL_EXPORT", "NO"); putlog "**************************"; putlog path "is not an email export"; putlog "IS_EMAIL_EXPORT=NO"; putlog "*************************"; end; run; %if %superq(IS_EMAIL_EXPORT)=YES %then %do; options nobomfile; %let export_filestmt=&export_filestmt ENCODING='UTF-8'; %end; /*******************************************/ /* END SECTION "Identify email export" */ /*******************************************/ /* S1134653 - Add BOM if utf-8 */ %if %nrbquote(&SysEncoding) = %str(utf-8) %then %let export_filestmt=&export_filestmt ENCODING='UTF-8' ; filename logfile temp lrecl=32767; data _null_; set &vards end=done; file logfile; if _n_ = 1 then do; put 'data ef_vartype (keep=exportOrder sasVarType);'; put ' length sasVarType $ 2;'; put ' set &input;'; put ' if _n_ > 1 then stop;'; end; put ' exportOrder=' exportOrder ';'; put ' sasVarType=vtypex("' outputname+(-1) '");'; put ' output;'; if done then do; put 'run;'; end; run; %inc logfile; filename logfile clear; data ef_varsort; merge &vards ef_vartype; by exportOrder; filename expfile temp lrecl=32767; data _null_; length _tmpvar $ 2000; %if &EXTENDEDCOLUMNNAMES = Y and &outputType = 7 %then %do; set &vars_extended_cols end=done; %end; %else %do; set &vards end=done; %end; file expfile; if _n_ = 1 then do; put "data _null_;"; put "%bquote(&export_filestmt;)"; /* S1189436 - check for final table count */ %if &expt_final_tbl_cnt. ne 0 %then %do; put "set &input;"; %end; put "length _matemp $ 2000 sasmat_out $4000;"; /* S0897280 - do not apply quotes when quote rule is set to "never quote values in export file" , removed checks for outputtype= 0 & 1 */ %if &outputType=7 and "eRule ne N %then %do; put "format _matemp $quote.;"; %end; %if &headerRow = Y %then %do; /* S1189436 - check for final table count */ %if &expt_final_tbl_cnt. eq 0 %then %do; put "header_row_replace=1;"; put "if header_row_replace=1 then do;"; %end; %else %do; put "if _n_ = 1 then do;"; %end; %end; end; %if &headerRow = Y %then %do; put "_matemp = '" outputname +(-1) "';"; %if &outputType = 4 %then %do; put 'put @' position "_matemp @;"; %end; %else %do; put "put _matemp @;"; %end; if done then put "put;" / "end;"; %end; run; /* S1189436 - check for final table count */ %if &expt_final_tbl_cnt. ne 0 %then %do; data _null_; length _tmpvar $ 2000 start_pos 8; set ef_varsort end=done; file expfile mod; start_pos =1; retain start_pos_end; if _n_ =1 then start_pos_end = position; if format ^= '' then do; _tmpvar = '_sasmat' || left(put(_n_,f8.)); /* begin:S0556482- Modified to remove tilde character from format variable */ if kindex(format,'~') eq 1 then do; notildeformat = ksubstr(format,2); put _tmpvar '= left(put(' outputname ', ' notildeformat '));'; end; else put _tmpvar '= left(put(' outputname ',' format '));'; /* end:S0556482*/ %if "eRule = A %then %do; put 'format ' _tmpvar ' $quote.;' ; %end; %else %if "eRule ne N %then %do; /* S0897280 - removed checks for outputtype= 0 */ %if &outputType=7 %then %do; put 'format ' _tmpvar ' $quote.;' ; %end; %end; %else %if &outputType ^= 7 and &outputType ^= 4 %then %do; put _tmpvar = outputname; %end; end; else do; if (""eRule"="A" and dataType="N") or dataType="DT" or dataType="D" or dataType="T" then do; _tmpvar = '_sasmat' || left(put(_n_,f8.)); length fmt $ 20; fmt="BEST12."; if dataType="DT" then fmt="DATETIME."; else if dataType="D" then fmt="DATE9."; else if dataType="T" then fmt="TOD."; /* S1326282 - do not set format when type is 8 */ if sasVarType='C' then do; if Type = 8 then do; _tmpvar = outputname; end; else do; put _tmpvar '= left(putn(' outputname ', "' fmt +(-1)'"));'; end; end; else put _tmpvar '= left(put(' outputname ', ' fmt '));'; end; else _tmpvar = outputname; %if "eRule=A %then %do; put 'format ' _tmpvar ' $quote.;' ; %end; %else %if "eRule ne N and &outputType=7 %then %do; if dataType^="N" then put 'format ' _tmpvar ' $quote.;'; %end; end; /* S0814504 - the format is already applied in the first do loop above , if we apply the format again to the variable it will print incorrect values not sure why the format was applied in case of quoteRule ^= A , need to test it for different conditions */ %if &outputType = 4 %then %do; /* if format ^= '' then do; %if "eRule^=A %then %do; put 'put @' position _tmpvar format '@ ;'; %end; %else %do; put 'put @' position _tmpvar '@ ;'; %end; end; else do; put 'put @' position _tmpvar '@ ;'; end; */ put 'sasmat_out = ksubstr(sasmat_out,' start_pos ',' position ') || left(' _tmpvar '); '; %end; %else %do; put 'put ' _tmpvar ' @ ;'; %end; if done then do; /* S1144393 - Added fix,single put statement used for output */ %if &outputType = 4 %then %do; put 'put @' start_pos_end ' sasmat_out ;'; put 'run;'; %end; %else %do; put 'put;' / 'run;'; %end; end; run; %end; %inc expfile; /*S0401805*/ %if (&SYSCC ne 0 and &SYSCC ne 4) and %symexist(SYSERRORTEXT) %then %do; /*send back the SYSERRORTEXT to user */ %let MAERROR=399;/*set a non used error code so that core can send error text back as is */ %let MAMsg=Macro[&sysmacroname.].SYSERRORTEXT=[&SYSERRORTEXT]; %return; %end; %mend;
When the DM agent runs it will use the sasfile.overrides maexpfil.sas first and not the one that comes with the dm agent.
2.1 Setting up sasfile.overrides ( detailed steps here 😞
- The directory for the sasfile.overrides needs to be in the dm agent server.
sasfile.overrides=/opt/sas/onprem/sascode
$ pwd
/opt/sas/onprem/sascode
$ ls -lR
drwxrwxr-x 2 sas sas 4096 Jun 8 11:15 sasmacro
drwxrwxr-x 2 sas sas 4096 May 5 2021 sasstp
./sasmacro:
total 48
-rw-rw-r-- 1 sas sas 11299 Jun 8 11:15 maexpfil.sas
-rw-rw-r-- 1 sas sas 1000 Mar 31 17:08 maspinit.sas
-rw-rw-r-- 1 sas sas 4614 Mar 18 06:16 mausrexp.sas
When the dm agent is upgraded someone needs to check if the newer maexpfil.sas has changed with respect to the one being used and act appropriately.
Want to review SAS Customer Intelligence 360? Gartner and G2 are offering a gift card or charitable donation for each accepted review. Use this link for G2 to opt out of receiving anything of value for your review.
SAS Customer Intelligence 360
Assess your marketing efforts with a free tool
Training Resources
SAS Customer Intelligence Learning Subscription (login required)
SAS' Peter Ansbacher shows you how to use the dashboard in SAS Customer Intelligence 360 for better results.
Find more tutorials on the SAS Users YouTube channel.
Want to review SAS Customer Intelligence 360? Gartner and G2 are offering a gift card or charitable donation for each accepted review. Use this link for G2 to opt out of receiving anything of value for your review.
SAS Customer Intelligence 360
Assess your marketing efforts with a free tool
Training Resources
SAS Customer Intelligence Learning Subscription (login required)