I'm trying to use Libre Office Basic to write user defined function for Libre Office Calc which runs Goal Seek as a function instead of me going to the menu and clicking.
What I want to be able to do is pass a cell as the first argument for the formula, the second argument to be the value I want to set the formula to, and the third argument to be the cell which contains the variable to be manipulated.
So for instance I want to type in cell A3 in calc =GSeek2(A1,5,A2) where A1 contains =A2 + 1 and A2 starts as 0 and have A3 equal to 4.
I think the formula and the cell to be manipulated need to be passed through the Goal Seek function as an address, but I'm not sure. I've tries the following code, but I keep getting "BASIC syntax error. Unexpected symbol: Goal." Anyone know where I'm going wrong?
Function GSeek2(Form As Range, Target as Double, Var as Range)
Form = Form.Address
Var = Var.Address
With Worksheets("Sheet1")
GSeek2 = .Range(Form).GoalSeek _
Goal:=.Value(Target).Value, _
ChangingCell:=.Range(Var)
End With
End Function
Related
I want to be able to run something like the following:
f:{[dt] syms:`sym1;eval parse"select from tbl where date = dt, sym=syms"}
f[.z.D]
Given the following :
tbl:([] date:2022.01.01 2022.01.01; Id:1000000 2000000; sym:`sym1`sym2;price:10 20;qty:3 4)
f:{[dt] syms:`sym1; ?[tbl;((=;`date;`dt);(=;`sym;`syms));0b;()]}
f1:{[dt] syms:`sym1; (?) . (tbl;((=;`date;`dt);(=;`sym;`syms));0b;())}
f2:{[dt] syms:`sym1; value (?;tbl;((=;`date;`dt);(=;`sym;`syms));0b;())}
f[.z.D] // works
f1[.z.D] // Gives Error - dt not recognized/out of scope
f2[.z.D] // Gives Error - dt not recognized/out of scope
Value within a function seems to not be able to detect the local variables and surprisingly (?) . also fails. (maybe because this in itself is a function and dt is not defined here?)
Is there any work around for this?
For context, I have a function that takes a select string/functional select, parses it, does some checks and manipulations on the functional form and returns a modified functional form.
I want users to be able to call this function from their own functions and that parameters they have defined in their function can be in the outputted functional form and that functional form can be valued some how.
I don't want users to be forced to pass more variables into my function etc.
What you need to do here is remove the backtick for dt and syms
I would also recommend using a backtick when calling your table name.
Further, you should make sure syms is enlisted if it is only one symbol.
So your function should be:
f:{[dt] syms:(),`sym1; ?[`tbl;((=;`date;dt);(=;`sym;syms));0b;()]}
If you parse your select statement you can see the correct form for functional selects:
q)parse "select from tbl where date=2022.01.01,sym=`sym1"
?
`tbl
,((=;`date;2022.01.01);(=;`sym;,`sym1)) // comma in front of `sym1 means enlist
0b
()
The backtick is not needed as this is a variable, defined in your function, it would be the same as doing:
?[`tbl;((=;`date;2022.01.01);(=;`sym;enlist `sym1));0b;()]
This should allow you to use your function correctly:
q)f[2022.01.01]
date Id sym price qty
---------------------------------
2022.01.01 1000000 sym1 10 3
For more information, see the kx documentation
I tried writing a Q Code which will allow me to pass parameters however I am getting a results as Qprojection. I tried using
qpython.sync() is returning a QProjection instead of the queried data
but solution isn't working(new to Q/kdb world)
Any ideas on what exactly I should change?
q.sync(
'''{[x;y;z]select from quotestackevent where date within(x;y),sym=z}''',
[np.datetime64('2018-04-14','D'), #start date
np.datetime64('2018-04-14','D'), #end date
np.string_('GBPUSD')])
In Q/KDB the functional format is {......}[x;y;z], with x y z being the arguments. If you have left a blank argument then the function becomes a projection.
qpython allows you to pass python arguments to a q function, with the format being q.sync('{......}',x,y,z).
In your example the square brackets is causing the inputs to be passed as a single array to the function, resulting in a projection. This can be fixed by removing the square bracket.
q.sync('{[x;y;z]select from quotestackevent where date within(x;y),sym=z}', np.datetime64('2018-04-14','D'), np.datetime64('2018-04-14','D'), np.string_('GBPUSD'))
Hope this helps!
I have a structure such as:
specimen.trial1 = 1
I now want to add another trial to the specimen, so that
specimen.trial1 = 1
specimen.trial2 = 2
I can do this without a problem within the workspace and command window. But, if I'm using a function to calculate the numbers for each trial (with dynamic fields), the new field and value erases the previous one. Eg:
function [specimen] = dummy(trial,value)
specimen.(trial) = value
end
run the function:
[specimen] = dummy('trial1',1)
then run the function again with different inputs, but keeping the structure intact in the workspace
[specimen] = dummy('trial2',2)
Instead of getting a structure with 2 fields, I get just one with Trial2 being the only field. Does that make any sense? What would like is to use the outputs of a function to progressively add to a structure.
Thank you,
Chris
Yes it makes sense, because you're creating a new struct specimen within your function.
Solution: pass the the previous specimen to the function as well.
function [specimen] = dummy(specimen,trial,value)
specimen.(trial) = value
end
and call:
[specimen] = dummy(specimen,'trial1',1)
or alternativly leave out the assignment at all and use the following
function [output] = dummy(value)
output = value
end
and call:
[specimen.trail1] = dummy(1)
which really depends on what you actually want to do. Put passing a name to a function which uses this name to define a struct is a little pointless unless you "use" that name otherwise. Also if you want to have input-dependent dynamic names you'd also go with the first alternative
I have a <850x1> cell called x. Each of the individual structures has a 'Tag' name and 'Data' cell with <7168x1 double> data values.
(i.e.
x{1,1}.Tag = 'Channel1', x{1,1}.Data= <7168x1 double>)
So, I want to go through the x cell, identify the structures with 'Channel1' Tag names and pull out that structure's data. Then, combine the data into a cell called Ch1. Here is my approach so far:
n=1:850
if x{n,1}.Tag == 'Channel1'
Ch1{:,n} = x{n,1}.Data;
end
However, this gives an error: Bad cell reference operation.
Any ideas what may be going wrong?
There are 2 issues here. First, your if statement will compare each entry in the string x{n,1}.Tag to each entry in the string 'Channel1'. If the dimensions are not the same, you will get an error. To fix this, you could use the string compare function, strcmp. The other issue is that you are assigning n to all values between 1 and 850 at once. This is the issue that is producing the actual error you are seeing. Instead, you want to step through each of these values one at a time with a for loop. I would suggest trying the following code:
for n=1:850
if strcmp(x{n,1}.Tag, 'Channel1')
Ch1{:,n} = x{n,1}.Data;
end
end
Actually I am coding a Matlab simulation where the AnchorID and SourceID will report to eachother. For example if I take an anchor 30 and source 50 it will collect all the agc values between these anchor and source and calculate rssi_dB and display them.Below mentioned is an example of anchor 30 and source id 50
Note: list of anchors ID's and source ID's are same. for e.g. 30 50 55 58 . These ID are both same for anchor and source.
function A30(BlinkSet)
for i=1:length(BlinkSet)
xAnchorID=30;
xSourceID=50;
a=BlinkSet{i}.AnchorID;
b=BlinkSet{i}.SourceID;
if xAnchorID==a && xSourceID==b
xagc=BlinkSet{i}.agc;
rssi_dB(i)=-(33+xagc*(89-33)/(29-1));
end
end
rssi_dB(rssi_dB==0)=[];
rssi_dBm=sum(rssi_dB(:))/length(rssi_dB);
disp([sprintf('The rssi value is %0.0f',rssi_dBm)]);
When I call the function in Matlab command window I get the rssi value of the above function.
Also my task is when I reciprocate the Anchor ID and source ID say Anchor as 50 and source as 30 like the function I have mentioned below I get an error which is mentioned after the function below.
function A50(BlinkSet)
for i=1:length(BlinkSet)
xAnchorID=50;
xSourceID=30;
a=BlinkSet{i}.AnchorID;
b=BlinkSet{i}.SourceID;
if xAnchorID==a && xSourceID==b
xagc=BlinkSet{i}.agc;
rssi_dB(i)=-(33+xagc*(89-33)/(29-1));
end
end
rssi_dB(rssi_dB==0)=[];
rssi_dBm=sum(rssi_dB(:))/length(rssi_dB);
disp([sprintf('The rssi value is %0.0f',rssi_dBm)]);
When I call this function I get an error as
??? Undefined function or variable "rssi_dB".
Error in ==> A50 at 14
rssi_dB(rssi_dB==0)=[];
Error in ==> main_reduced at 26
A50(BlinkSet);
In main function I have coded like this,
%A30(BlinkSet);
A50(BlinkSet);
Any help is highly appreciated.
In both of these functions, you only create the variable rssi_dB if execution enters the if statement within the loop (i.e., if xAnchorID==a && xSourceID==b is at some point true). Clearly, this code is never executed in your A50 function. Without knowing what is in BlinkSet it's a bit difficult to diagnose the exact problem, but this is the cause at least.
As a side note: it's not a good idea to create two separate functions to do this job when their code is almost identical. You should add an input argument to your function that allows it to do the job of both. In this particular case, all that changes is the value of xAnchorID and xSourceID, so you could just pass these in:
function srcToAnchorRssi(BlinkSet, xSourceID, xAnchorID)
% The rest of the function stays the same!
If you want to provide some defaults for these arguments, you can do, e.g.:
if nargin < 3 || isempty(xAnchorID), xAnchorID = 50; end
if nargin < 2 || isempty(xSourceID), xSourceID = 30; end
It's always a good idea to include an isempty in statements of this sort, so that your function supports syntax like myFunction(myArg1, [], myArg3). Also note that the order of the operands to || is crucial; if you did if isempty(theArgument) || nargin < theArgumentNumber and the user did not pass theArgument, then it would error in the isempty because theArgument would not exist as a local variable. We can get around this by swapping the operands' order because MATLAB is smart enough to know it doesn't have to evaluate the right operand if the left operand is true (note that this is also the case in many other programming languages).