Skip to content

Commit

Permalink
fix for API call issue
Browse files Browse the repository at this point in the history
recent changes to SEXP -> XLOPER translation caused problems for API calls
with multiple values; that's been fixed.  also a documentation fix in
examples.R.
  • Loading branch information
duncanwerner committed Jun 20, 2016
1 parent 96d73d4 commit 7b62bb1
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 12 deletions.
2 changes: 1 addition & 1 deletion BERT/BERT_Version.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#ifndef __BERT_VERSION_H
#define __BERT_VERSION_H

#define BERT_VERSION L"0.72"
#define BERT_VERSION L"0.73"

#endif // #ifndef __BERT_VERSION_H

48 changes: 43 additions & 5 deletions BERT/RInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1285,17 +1285,28 @@ bool CheckExcelRef(LPXLOPER12 rslt, SEXP s)
/**
* reimplementation of translation
*/
void SEXP2XLOPER(LPXLOPER12 xloper, SEXP sexp, bool inner = false, int r_offset = 0) {
void SEXP2XLOPER(LPXLOPER12 xloper, SEXP sexp, bool inner = false, int r_offset = 0, bool api_call = false ) {

// we want to fill up the space, not showing errors if the data
// is smaller than the excel range. the only way to do that is
// with strings ("") -- the types nil and missing don't do it

// NOTE: while this is good for returning values from functions, it's
// not good for Excel API functions from the shell, which also use this
// function. in fact it breaks them completely. so need a flag to repair...

// (1) API calls should set the "inner" flag to prevent the "caller" lookup.
// both because it's time-consuming and because it won't work properly.
// actually, use a separate flag...
//
// (2) API calls should pass explicit range sizes...


int xlrows = 1;
int xlcols = 1;
int xllen = 1;

if (!inner) {
if (!inner && !api_call ) {

XLOPER12 xlrslt;
Excel12(xlfCaller, &xlrslt, 0, 0);
Expand Down Expand Up @@ -1378,9 +1389,36 @@ void SEXP2XLOPER(LPXLOPER12 xloper, SEXP sexp, bool inner = false, int r_offset
n_cols = Rf_ncols(sexp);
}

if (api_call) {

if (Rf_isFrame(sexp)) {
n_cols = len + 1;
SEXP sexp_col = PROTECT(VECTOR_ELT(sexp, 0));
n_rows = Rf_length(sexp_col) + 1;
UNPROTECT(1);
};

xlrows = n_rows;
xlcols = n_cols;
xllen = xlrows * xlcols;

if (xllen > 1) {
xloper->xltype = xltypeMulti;
xloper->val.array.rows = xlrows;
xloper->val.array.columns = xlcols;
xloper->val.array.lparray = new XLOPER12[xlrows * xlcols];
for (int i = 0; i < xllen; i++) {
xloper->val.array.lparray[i].xltype = xltypeStr | xlbitDLLFree;
xloper->val.array.lparray[i].val.str = emptyStr;
}
}
firstRef = xloper->xltype == xltypeMulti ? xloper->val.array.lparray : xloper;

}

n_rows = MIN(n_rows, xlrows);
n_cols = MIN(n_cols, xlcols);

int index = 0;

if (Rf_isLogical(sexp)) {
Expand Down Expand Up @@ -2029,11 +2067,11 @@ SEXP ExcelCall(SEXP cmd, SEXP data)
{
SEXP tmp = VECTOR_ELT(data, i);
if (!CheckExcelRef(xdata[i], tmp))
SEXP2XLOPER(xdata[i], tmp);
SEXP2XLOPER(xdata[i], tmp, false, 0, true );
}
break;
case STRSXP:
SEXP2XLOPER(xdata[i], STRING_ELT(data, i));
SEXP2XLOPER(xdata[i], STRING_ELT(data, i), false, 0, true);
break;
case INTSXP:
xdata[i]->xltype = xltypeInt;
Expand Down
9 changes: 5 additions & 4 deletions Examples/ExcelFunctions.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
# available in the console but don't get added as Excel functions.
#

if( any(search() == "BERT.Excel")){
suppressMessages(detach( BERT.Excel ));
}

BERT.Excel <- new.env();
with( BERT.Excel, {

Expand Down Expand Up @@ -449,10 +453,7 @@ Activate.Sheet <- function( name ){

#
# now attach to add them to the console search path
# (UPDATE: only once, in case this file is reloaded)
#

if( !any(search() == "BERT.Excel")){
suppressMessages(attach( BERT.Excel ));
}
suppressMessages(attach( BERT.Excel ));

7 changes: 5 additions & 2 deletions Examples/functions.R
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# R functions exposed in Excel. These are just some simple
# examples. See the page
#
# http://bert-org/example-functions
# http://bert-toolkit.org/example-functions
#
# for more examples. You can add functions directly to this
# file, but it's probably better to put them in a separate file
Expand Down Expand Up @@ -76,4 +76,7 @@ source( "ExcelFunctions.R" );
# BERT$ReloadStartup, but you can pass a function to run any arbitrary
# R code when the file changes.

# WatchFile( paste( BERT$HOME, "\\functions.R", sep=""))
# BERT$WatchFile( file.path( BERT$HOME, "functions.R" ))



0 comments on commit 7b62bb1

Please sign in to comment.