Page 1 of 1

Names of Cubes in a server

Posted: Mon Feb 01, 2010 7:50 pm
by samuvk
I'm totally deseperate because I've been working on this for a week and I can't see the mistake or fix this code, if some could help me I'll be so thankful.

I'm trying to get the names of the cubes in a server and I having a problem with the last function:

Call TM1ValStringGet_VB(hUser, hName, name, 75)

I am using the same process before to get the name of a server and I don't have any problem, but I don't know why for the names of the cubes, that it should be the name, it doesn't works.

Code: Select all

'Connect to the server
hPool = TM1ValPoolCreate(hUser)
hPool2 = TM1ValPoolCreate(hUser)
hServer = TM1SystemServerConnect(hPool, vServerName, vUserName, vPassword)

'Return the name of the server: It's works
vsServerName = TM1ObjectPropertyGet(hPool2, hServer, TM1ObjectName())
Call TM1ValStringGet_VB(hUser, vsServerName, sServerName, 75)

'Retrieve a count of the number of cubes defined in the server-
Dim hCount As Long
hCount = TM1ObjectListCountGet(hPool, hServer, TM1ServerCubes)

'Convert the count to something you can use-
Dim countOfCubes As Long
countOfCubes = TM1ValIndexGet(hUser, hCount)

'Loop around retrieving each cube object from the server, until index = countOfCubes-
Dim hCube As Long
Dim index As Long
index = 2
hCube = TM1ObjectListHandleByIndexGet(hPool, vServerName, TM1ServerCubes(), index)

'Retrieve the name of the cube using the TM1ObjectName property-
hName = TM1ObjectPropertyGet(hPool, hCube, TM1ObjectName())

'Convert the cube name to a string-
Dim name As String * 75
'When I try to execute this Sub, Excel give me a fatal error and Excel closes.
Call TM1ValStringGet_VB(hUser, hName, name, 75)
Thank you very much in advance to everyone for your help

Re: Names of Cubes in a server

Posted: Mon Feb 01, 2010 8:35 pm
by Mike Cowie
Hi:

I believe you need to pass a *handle* to the index to retrieve your cube object, not the actual index. For example:

Code: Select all

Dim hCube As Long
Dim index As Long
Dim indexHnd As Long
index = 2
indexHnd = TM1ValIndex(hPool, index)
hCube = TM1ObjectListHandleByIndexGet(hPool, vServerName, TM1ServerCubes(), indexHnd)
Your problem is that I suspect your code is returning an error handle for hCube instead of a handle to the cube object. As a result, your attempt to get the name property will never work because you're asking for the property of an error.

If you're going to use the TM1 C/VB API, you should first think about whether or not there's an easier way to do what you're trying to do - the VB/C API that you are using is not trivial and using something like Excel VBA with the TM1 Excel/Macro function set could be much more productive - also, there are many more people on this forum who are familiar with that. The code you're trying to run here is very straightforward in Excel VBA.

If you must use the TM1 C/VB API then you absolutely need to get familiar with functions that help you test return values. For example, if you knew how use functions like TM1ValType and TM1ValObjectType, for starters, you could have tested the value in hCube and seen that it was not an object, but an error value (assuming that is the problem).

Regards,
Mike

Re: Names of Cubes in a server

Posted: Mon Feb 01, 2010 9:48 pm
by samuvk
Hi Mike,

Thank you very much for your help.

What do you refer to TM1 Excel/Macro ? It's some kind of macro that I can run as a Excel Macro, there are code for that, or are you refering just to the TM1 addin that appear at the top of the excel file, where you can connect to the server as a user?

I trying to use the straigh TM1 API code, because it's the only manual / information that I have, but I very open to use any other way to do thing if are easier. Where can I find information / manuals for learn how to work with the TM1 Excel/Macro?

I tried to used the code that you recommend me, but didn't work

Code: Select all

Dim hCube As Long
Dim index As Long
Dim indexHnd As Long
index = 2
indexHnd = TM1ValIndex(hPool, index)
hCube = TM1ObjectListHandleByIndexGet(hPool, vServerName, TM1ServerCubes(), indexHnd)

Thank you very much again

Re: Names of Cubes in a server

Posted: Mon Feb 01, 2010 9:50 pm
by Alan Kirk
samuvk wrote:Hi Mike,

Thank you very much for your help.

What do you refer to TM1 Excel/Macro ?
I think he's referring to the method that Martin told you to use last week.

Re: Names of Cubes in a server

Posted: Mon Feb 01, 2010 10:10 pm
by Mike Cowie
Hi:

The Excel/VBA API I'm talking about is covered in the TM1 reference guide. You can get that in PDF form or online:
http://publib.boulder.ibm.com/infocente ... 201FD.html

This is available when you have the TM1 add-in loaded in Excel. You have access to the macro functions listed as well as all of the TM1 Excel worksheet functions. If you were trying to loop through and get a list of cube names in Excel VBA, you could use the TM1 Excel functions like DIMSIZ() and DIMNM() against the "}Cubes" dimension. If this would work for you, you should invest some time in it - it is far easier to work with than the C/VB API you are trying to use.

I'm sorry your C/VB API code is still not working. As I mentioned in my comment, you need to learn how to use the TM1ValType and, possibly, the TM1ValObjectType functions to test the type of value being returned to you. The TM1ValErrorString_VB and TM1ValErrorCode functions are also useful in debugging when you get an error returned. Without these tools, you'll be flying blind. For example, you could check the type of value in hCube to see if it's an object or an error:

Code: Select all

If TM1ValType(hUser, hCube) = TM1ValTypeObject() Then
  'You have a cube, you should be able to get a handle to its name

ElseIf TM1ValType(hUser, hCube) = TM1ValTypeError() Then
  'You have an error - use TM1ValErrorString_VB to get the error message

End If
Again, Alan and I (and Martin before us) would strongly recommend using the Excel/VBA API if possible, especially if where you're trying to use this is in Excel anyway (and it sounds like it is).

Regards,
Mike

Re: Names of Cubes in a server

Posted: Tue Feb 02, 2010 2:41 am
by Alan Kirk
samuvk wrote: I tried to used the code that you recommend me, but didn't work

Code: Select all

Dim hCube As Long
Dim index As Long
Dim indexHnd As Long
index = 2
indexHnd = TM1ValIndex(hPool, index)
hCube = TM1ObjectListHandleByIndexGet(hPool, vServerName, TM1ServerCubes(), indexHnd)
I would like to reiterate everything that Mike told you, and that I told you before that, and that Martin told you before that. The VB/C API is only for when you have no alternative, and you need to know what you're doing.

Having said that, and having now had a chance to look at your code, I believe that your main problem (aside from the one that Mike identified) is here:
hCube = TM1ObjectListHandleByIndexGet(hPool, vServerName, TM1ServerCubes(), indexHnd)
From your earlier code it appears that vServerName is a value capsule containing a string which specifies the server name. It's what you used in the TM1SystemServerConnect function.
hServer = TM1SystemServerConnect(hPool, vServerName, vUserName, vPassword)
What the TM1ObjectListHandleByIndexGet function actually needs is a handle to the server object, not a value capsule containing the server's name. These are not at all the same thing.

This emphasises another thing that you need to be aware of with with the API; it will cut you no slack at all. The API's idea of "graceful error handling" is to crash your application, and it will do so if you pass the wrong argument, or the wrong argument type to it.

As Mike said, and me before him, you need to test every value capsule before you use it. But be aware that even that won't guarantee that it won't crash if you pass the wrong type of handle as you're apparently doing here.

Re: Names of Cubes in a server

Posted: Tue Feb 02, 2010 4:24 pm
by samuvk
Thank you very much all.

I'll try to start to learn the Excel/VBA API with the link Mike sent me.

I'm sorry for asking too much, but I'm new on all of that and English is not my mother language so it's really difficult for me some times to see things that are easy to see for other.

Thank you very much again all for your help

Re: Names of Cubes in a server

Posted: Tue Feb 02, 2010 7:39 pm
by Martin Ryan
samuvk wrote: I'm sorry for asking too much, but I'm new on all of that and English is not my mother language so it's really difficult for me some times to see things that are easy to see for other.
It's actually not easy for others either! I've been working with TM1 for six years now and very very rarely dip into the API, it's not well documented, nor does it operate gracefully. As Alan points out it's idea of error handling is to crash Excel and TM1. This is why we're all trying to suggest that where possible you make use of the much tidier and easier functions that are already available via macros. These are all pretty well handled and take the edge off the coding. You'll find a list of all the Macros and Worksheet functions that are at your disposal in the help file. In my version (9.3) it's Contents -> TM1 Reference Guide -> TM1 Macro Functions. You can also call all the functions listed under the Worksheet Functions. This is what I used in my previous post.

The other bonus is that with Macro/Worksheet functions in VBA you'll get a lot more support out of this forum. As the API is difficult to work with, there's only a small set of users with the skill set to help you here.

Martin

Re: Names of Cubes in a server

Posted: Thu Dec 23, 2010 5:28 am
by Selvin
Hi, can i get the code to connect and execute a process in TM1 through .net code. Thanks in advance

Re: Names of Cubes in a server

Posted: Thu Dec 23, 2010 6:17 am
by Alan Kirk
Selvin wrote:Hi, can i get the code to connect and execute a process in TM1 through .net code. Thanks in advance
In which language, and exactly how far have you gotten in trying to do this? Have you, for instance, looked at the TM1_NET_API_Doc.chm file which IBM laughingly tries to pass off as the documentation for the .Net API? (And which I continue to regard as bordering on useless as anything other than a class reference document, but which does at least serve that latter purpose.) Do you understand how to call the Applix.TM1.API Assembly from your project, or are you even stuck at that point?

Re: Names of Cubes in a server

Posted: Thu Dec 23, 2010 1:57 pm
by Selvin
Hi Alan.. thanks for ur reply. what i have done so far is,

Registering the DLL by
[DllImport(@"C:\\Program Files\\Cognos\\TM1\\bin32\\tm1api.dll", EntryPoint = "TM1APIInitialize")]
public static extern void TM1APIInitialize();

[DllImport(@"C:\\Program Files\\Cognos\\TM1\\bin32\\tm1api.dll")]
public static extern int TM1SystemOpen();

[DllImport(@"C:\\Program Files\\Cognos\\TM1\\bin32\\tm1api.dll")]
public static extern void TM1SystemAdminHostSet(int hUser, [MarshalAs(UnmanagedType.LPStr)]string sAdminHost);

[DllImport(@"C:\\Program Files\\Cognos\\TM1\\bin32\\tm1api.dll")]
public static extern int TM1ValPoolCreate(int User);

[DllImport(@"C:\\Program Files\\Cognos\\TM1\\bin32\\tm1api.dll")]
public static extern int TM1ValString(int hPool, [MarshalAs(UnmanagedType.LPStr)]string st, int maxSize);

[DllImport(@"C:\\Program Files\\Cognos\\TM1\\bin32\\tm1api.dll")]
public static extern int TM1SystemServerConnect(int hPool, int sServerName, int sClientName, int sPassword);

[DllImport(@"C:\\Program Files\\Cognos\\TM1\\bin32\\tm1api.dll")]
public static extern int TM1ValType(int hUser, int vServerObject);

[DllImport(@"C:\\Program Files\\Cognos\\TM1\\bin32\\tm1api.dll")]
public static extern int TM1ValTypeObject();

[DllImport(@"C:\\Program Files\\Cognos\\TM1\\bin32\\tm1api.dll")]
public static extern int TM1ValTypeError();

[DllImport(@"C:\\Program Files\\Cognos\\TM1\\bin32\\tm1api.dll")]
public static extern int TM1ValErrorCode(int hUser, int vServerObject);

[DllImport(@"C:\\Program Files\\Cognos\\TM1\\bin32\\tm1api.dll")]
public static extern string TM1ValErrorString(int hUser, int vServerObject);

[DllImport(@"C:\\Program Files\\Cognos\\TM1\\bin32\\tm1api.dll")]
public static extern int TM1ProcessExecute(int hPool, int hProcess, int hParametersArray);

[DllImport(@"C:\\Program Files\\Cognos\\TM1\\bin32\\tm1api.dll")]
public static extern int TM1SystemServerConnectIntegratedLogin(int hPool, int vServerName);

[DllImport(@"C:\\Program Files\\Cognos\\TM1\\bin32\\tm1api.dll")]
public static extern void TM1APIFinalize();

[DllImport(@"C:\\Program Files\\Cognos\\TM1\\bin32\\tm1api.dll")]
public static extern int TM1ServerCubes();

[DllImport(@"C:\\Program Files\\Cognos\\TM1\\bin32\\tm1api.dll")]
public static extern int TM1ValIndex(int hPool, int i_CubesIdx);

[DllImport(@"C:\\Program Files\\Cognos\\TM1\\bin32\\tm1api.dll")]
public static extern int TM1ObjectListHandleByIndexGet(int hPool, int vServerObject, int TM1ServerC, int TM1ValI);

In the Button click i want to execute the process
protected void btnUpdate_Click(object sender, EventArgs e)
{
//TM1APIInitialize();
//int hUser = TM1SystemOpen();
//TM1SystemAdminHostSet(hUser, "INFPWH0040");
//int hPool = TM1ValPoolCreate(hUser);

//string strServerName = "INFPWH0040";

//int vServerName = TM1ValString(hPool, strServerName.Trim(), 0);

//int hServer = TM1SystemServerConnectIntegratedLogin(hPool, vServerName);

//if (TM1ValType(hUser, hServer) == TM1ValTypeObject())
//{
// TM1ProcessExecute(hPool, 2, 1);
//}
//if (TM1ValType(hUser, hServer) == TM1ValTypeError())
//{
// int nErrCode = TM1ValErrorCode(hUser, hServer);
// string szErrMsg = TM1ValErrorString(hUser, hServer);
// //Console.WriteLine(nErrCode + ": " + szErrMsg);
//}

//TM1APIFinalize();

//////////////////////////////////////////
TM1APIInitialize();
int hUser = TM1SystemOpen();
//string st = "http://172.25.34.95/Tm1Web/";
string st = "INFPWH0040";
TM1SystemAdminHostSet(hUser, st);
int hPool1 = TM1ValPoolCreate(hUser);

int hPool2 = TM1ValPoolCreate(hUser);
string sUserName = "admin";
string sServerName = "revapps";
string sPassword = "";
//string sProcess = "fghy";
int vStringLength = 10;

//int vProcess = TM1ValString(hPool1, sProcess, vStringLength);
int vUserName = TM1ValString(hPool1, sUserName, vStringLength);
int vServerName = TM1ValString(hPool1, sServerName, vStringLength);
int vPassword = TM1ValString(hPool1, sPassword, vStringLength);
int vServerObject = TM1SystemServerConnect(hPool1, vServerName, vUserName, vPassword);

int TM1ServerC = TM1ServerCubes();
int TM1ValI = TM1ValIndex(hPool1, 0);
string name = System.Security.Principal.WindowsIdentity.GetCurrent().Name;

if (TM1ValType(hUser, vServerObject) == TM1ValTypeError())
{
int nErrCode = TM1ValErrorCode(hUser, vServerObject);
string szErrMsg = TM1ValErrorString(hUser, vServerObject);
}
else
{
//vhCubes = TM1ObjectListCountGet(hPool, hServer, TM1ServerCubes());
int hCube = TM1ObjectListHandleByIndexGet(hPool1, vServerObject, TM1ServerC, TM1ValI);


int t = TM1ProcessExecute(hPool1, hCube, 5); }

}

Error : like Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Please advice me what is wrong and how to achieve this..

Thanks

Re: Names of Cubes in a server

Posted: Fri Dec 24, 2010 6:14 am
by Selvin
Hi have anyone tried this... expecting help from u..

Re: Names of Cubes in a server

Posted: Fri Dec 24, 2010 6:33 am
by Alan Kirk
Selvin wrote:Hi have anyone tried this... expecting help from u..
Someone else may, but it looks like you're using C++ which I haven't worked with the API in. Odds are that someone, at some time, has done so (whether they've done so to run a process is another matter), but you might have a problem finding them at this time of the year when so many businesses have closed for the holiday season. You may have to wait a while to get an answer to this.

Re: Names of Cubes in a server

Posted: Mon Dec 27, 2010 9:51 am
by Selvin
Thanks Alan.. will try

Re: Names of Cubes in a server

Posted: Wed Jan 12, 2011 5:10 am
by Selvin
Hi,

Did anyone found any solution? I need to execute a TI process through c#.net using the API.