The Origin Forum
File Exchange
Try Origin for Free
The Origin Forum
Home | Profile | Register | Active Topics | Members | Search | FAQ | Send File to Tech support
Username:
Password:
Save Password
Forgot your Password? | Admin Options

 All Forums
 Origin Forum for Programming
 LabTalk Forum
 Using Project Explorer names for data files path
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic Lock Topic Edit Topic Delete Topic New Topic Reply to Topic

Clairekun

Germany
175 Posts

Posted - 03/19/2020 :  7:11:37 PM  Show Profile  Edit Topic  Reply with Quote  View user's IP address  Delete Topic
Origin Ver. and Service Release (Select Help-->About Origin): 2018b
Operating System: Windows 10

I have a folder structure in Project Explorer somewhat mimicking that of data files path:

WINDOWS EXPLORER


PROJECT EXPLORER


Here, the string register %X would be D:\Lab data\Samples and %G would be "Technique".

I want to, either select files from the folder "Time xx" via dlgpath, or use findfiles command. Workbooks and worksheets were created before importing.

Since there are multiple "Time xx" folders, I need a way to define a path common to every selected workbook. This way, I would run the same script for every workbook separately.

The files path is D:\Lab data\Samples\Technique\Temperature 1\Time 1a and so on.

If I write %X%G, I get to D:\Lab data\Samples\Technique\. However, that is the last folder I can reach, even if I purposedly named the project and Project Explorer subfolders to match those of Windows.

In an attempt to get to D:\Lab data\Samples\Technique\Temperature n\Time xx, I have tried:
- %X%@P, not working. %@P uses forward slashes, while %X uses backslashes, so I tried to call Temperature n and Time xx folders separately.
- %X%G%@F does not return D:\Lab data\Samples\Technique\Temperature n\. Of course, adding page.longname$ at the end does not get to Time xx folder.
- Neither does %X%G+%@F nor %X%G\%@F
- To maintain the pattern, I tried to assign %A and %B to %@F and page.longname$, respectively, and type the path as %X%G%A%B, with and without backslashes, plus signs, quotes and all I could think of.
- %X%G+"\Temperature 1\Time 1a" is not working, either.

What am I doing wrong? I'm sure I'm misunderstanding some concept.

Thank you.

YimingChen

1669 Posts

Posted - 03/20/2020 :  09:26:06 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hi,

You can use substitute method of string to replace forward slashes by back slashes then append to the full path.
https://www.originlab.com/doc/LabTalk/ref/String-obj#Substitute

James

Edited by - YimingChen on 03/20/2020 09:26:27 AM
Go to Top of Page

Clairekun

Germany
175 Posts

Posted - 03/23/2020 :  09:06:56 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hello,

Thanks for your suggestion. I tried and an error was shown:
string tgpath$ = %@P.Substitute("/","\",0)$;

Error displayed:
%@P.Substitute("/","\",0)$
string expression error!
TGPATH:failed to add variable to local stack!
#Command Error!


I strongly suspect that, once you use %X-like string registers when specifying a path, nothing else can go in there, not even %@-like strings, since I tried both text and %@ along with them and nothing seemed to work.

Also, working with string registers like I did with the code above seems to be a no-no, too - checked this at https://www.originlab.com/doc/LabTalk/guide/String-registers and, indeed, string registers used by the system cannot be used as string variables. I also tried to retrieve the text between slashes using tokens and "\" as a separator, but was unsucessful.

I might need to approach the problem differently and I will most likely need help from you guys again. Let me think of it for a bit and I'll open a new topic if it's too different from this one (unless you recommend otherwise).

I believe my first post was unnecessarily complicated; I tried to make it as clear as possible, but I believe I failed miserably; I'm terribly sorry.

Edited by - Clairekun on 03/23/2020 09:09:15 AM
Go to Top of Page

Chris D

428 Posts

Posted - 03/23/2020 :  1:47:30 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hi Claire,

Try focusing on and rephrasing exactly what you want to do. It is a bit confusing what you goal is.



Thanks,
Chris Drozdowski
Originlab Technical Support
Go to Top of Page

YimingChen

1669 Posts

Posted - 03/23/2020 :  4:36:47 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
You need first define a string, please try this:

string tgpath$ = %@P;
string tgpathNew$ = tgpath.Substitute("\\","/")$;


quote:
Originally posted by Clairekun

Hello,

Thanks for your suggestion. I tried and an error was shown:
string tgpath$ = %@P.Substitute("/","\",0)$;

Error displayed:
%@P.Substitute("/","\",0)$
string expression error!
TGPATH:failed to add variable to local stack!
#Command Error!


I strongly suspect that, once you use %X-like string registers when specifying a path, nothing else can go in there, not even %@-like strings, since I tried both text and %@ along with them and nothing seemed to work.

Also, working with string registers like I did with the code above seems to be a no-no, too - checked this at https://www.originlab.com/doc/LabTalk/guide/String-registers and, indeed, string registers used by the system cannot be used as string variables. I also tried to retrieve the text between slashes using tokens and "\" as a separator, but was unsucessful.

I might need to approach the problem differently and I will most likely need help from you guys again. Let me think of it for a bit and I'll open a new topic if it's too different from this one (unless you recommend otherwise).

I believe my first post was unnecessarily complicated; I tried to make it as clear as possible, but I believe I failed miserably; I'm terribly sorry.

Go to Top of Page

Clairekun

Germany
175 Posts

Posted - 03/24/2020 :  04:49:48 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
quote:
Originally posted by Chris D

Hi Claire,

Try focusing on and rephrasing exactly what you want to do. It is a bit confusing what you goal is.



Thanks,
Chris Drozdowski
Originlab Technical Support



Sorry about this. Okay, second try.

- Origin file is located at D:\Lab data\Samples\Technique.opju
- Datafiles are located at D:\Lab data\Samples\Technique\Temperature x\Time xx\datafiles.txt
- "Technique.opju" and the folder "Technique" have the same name (not sure this was clear enough).
- Project explorer tree structure is Technique (= Technique.opju)\Temperature x\Time xx (workbook)- Datafiles (worksheets).

What I did in Project Explorer:
- Create Temperature x folders manually.
- Use a code to automatically create workbooks named Time xx:
dlgPath init:=%X%G; //Gets to D:\Lab data\Samples\Technique\; I select Temperature X folder manually
findFolders;
int nn = folder.GetNumTokens(CRLF);
string strTemp$; 
for(int ii = 1; ii <=nn; ii++) 
{
	strTemp$ = folder.GetToken(ii, CRLF)$; 
	newbook name:=strTemp$ option:=lsname; // Creates books named Time xx
}

*Note: The above code only works once. If I try to rerun it for a different Temperature X folder, nothing happens. I have to duplicate newly created workbooks and move them. Any comment as to why would be greatly appreciated.

- Use another code to import Time xx datafiles as sheets (too long, won't post here unless necessary).

The fact that I need to run the import script per workbook is why a unified path where I could use project explorer items as variables when importing, would be ideal (since they have the same names), so that I could get right to Time xx folder automatically.

Right now, all I can do is %X%G and navigate from there. I currently use dlgFile command to select the files. If this unified path could be secified, I could simply use dlgPath and findfiles to get them all in one go, even if I had to rerun the script for every workbook.

I don't know if this could be extrapolated to stop needing to select every workbook but, for now, this would do.

I hope this was clearer.
Go to Top of Page

Chris D

428 Posts

Posted - 03/24/2020 :  2:31:24 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
If you are doing this so that you can import files into a Project Explorer hierarchy that is the same as the Disk file system, try the "Import Files from a Folder" App:

https://www.originlab.com/FileExchange/details.aspx?v=0&fid=394

Thanks,
Chris Drozdowski
Originlab Technical Support
Go to Top of Page

YimingChen

1669 Posts

Posted - 03/24/2020 :  4:00:31 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Can you use findFolders to get all the Temperature XX folders under your %X%G folder? Then loop over all Temperature XX folders, search for subfolders in it and create workbook for each subfolder? See script below:


string strPath$ = %X%G;
path$= strPath$;
findFolders;  //  Find all Temperature XX folders. 
string froot = folder$;
int n = froot.GetNumTokens(CRLF);
string strTemp$; 
for(int ii = 1; ii <=n; ii++) 
{
	path$ = strPath$ + "\" + froot.GetToken(ii, CRLF)$; 
	findFolders;  //  Find all folders under current Temperature XX folder.
	int nn = folder.GetNumTokens(CRLF);
	string strTemp$;
	for(int jj = 1; jj <=n; jj++) 
	{		
		strTemp$ = folder.GetToken(jj, CRLF)$; 
		newbook name:=strTemp$ option:=lsname; 
	}	
}


James

Edited by - YimingChen on 03/24/2020 4:00:58 PM
Go to Top of Page

Clairekun

Germany
175 Posts

Posted - 03/25/2020 :  02:30:44 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
quote:
Originally posted by Chris D

If you are doing this so that you can import files into a Project Explorer hierarchy that is the same as the Disk file system, try the "Import Files from a Folder" App:

https://www.originlab.com/FileExchange/details.aspx?v=0&fid=394

Thanks,
Chris Drozdowski
Originlab Technical Support



Although the structure is pretty similar, it's not quite the same, as last subfolder in Windows does not exist in Origin. I haven't tried it yet, but the app doesn't seem to allow customization (only importing file structure along with the files or not). Good app, though, might use it for other projects.

Thank you.
Go to Top of Page

Clairekun

Germany
175 Posts

Posted - 03/25/2020 :  06:03:23 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
quote:
Originally posted by YimingChen

Can you use findFolders to get all the Temperature XX folders under your %X%G folder? Then loop over all Temperature XX folders, search for subfolders in it and create workbook for each subfolder? See script below:


string strPath$ = %X%G;
path$= strPath$;
findFolders;  //  Find all Temperature XX folders. 
string froot = folder$;
int n = froot.GetNumTokens(CRLF);
string strTemp$; 
for(int ii = 1; ii <=n; ii++) 
{
	path$ = strPath$ + "\" + froot.GetToken(ii, CRLF)$; 
	findFolders;  //  Find all folders under current Temperature XX folder.
	int nn = folder.GetNumTokens(CRLF);
	string strTemp$;
	for(int jj = 1; jj <=n; jj++) 
	{		
		strTemp$ = folder.GetToken(jj, CRLF)$; 
		newbook name:=strTemp$ option:=lsname; 
	}	
}


James


Thanks for your help. On a side note, but relevant to this issue: I can only run the script once in the project. Running it inside the other PE folders has no result at all; the reason behind this, I've learned, is that Time xx names are the same in Temp x folders:

Temp 1 > Time a, b, c, d.
Temp 2 > Time a, b, c, d.
Temp 3 > Time a, b, c, d.
(This made me realise the folder structure in my original post is wrongly named, sorry)

If workbooks named Time a, b, c, d are generated for Temp 1, since the names already exist, no more workbooks will be created for Temp 2, 3.

I see this code would create all workbooks in the same project explorer folder. I encountered a weird problem here: while there are 4 folders, only 3 workbooks are created. I checked folder.GetNumTokens(CRLF)$=; to see if the problem was in the counting, but it returned 4 correctly.

There are 3 different temperatures, so the number of Temperature xx folders is 3. Could it be that it's mixing it up somehow?

I made an experiment which wielded even weirder results. I made a new, empty Temperature xx folder, so now there are 4 Temperature folders:

Temp 1 > Time a, b, c, d.
Temp 2 > Time a, b, c, d.
Temp 3 > Time a, b, c, d.
Temp 4 > (empty)

When I run the script, this time, 8 books are created: 4 named correctly, and another 4 whose names follow the Book# pattern. After some more experimenting, it so happens that, even if folder.GetNumTokens(CRLF)$=4, the number of books created depends on froot.GetNumTokens(CRLF).

If I create 4 subfolders using the same pattern as the existing ones (Temp 4 > Time a, b, c, d), this time, 4 folders correctly named are created, and nothing else. If I change a subfolder name (Temp 4 > Time a, b, c, w), 5 new workbooks appear named Time a, b, c, d, w.

If I delete one (Temp 4 > Time a, b, c), 5 folders are created: 4 correctly named, and 1 named Book#. If I delete two (Temp new > Time a, b), I get 4 Time xx + 2 Book#, and so on. It is as if it expected to get 4 Time xx folders every time, and creates Book# until that number is satisfied.

If I create a 5th Temperature folder following the same structure:

Temp 1 > Time a, b, c, d.
Temp 2 > Time a, b, c, d.
Temp 3 > Time a, b, c, d.
Temp 4 > Time a, b, c, d.
Temp 5 > Time a, b, c, d.

9 workbooks are created: 4 correctly named, and 5 Book#. This confirms the number of workbooks created, even if folder.GetNumTokens(CRLF)=4, is dependent on the number of Temperature folders exclusively (froot.GetNumTokens(CRLF)).

So, for now, the problems with the code are:

- Successfully reads number and name of subfolders, but applies it wrongly.
- No new workbooks are created if the names already exist. I believe I've stumbled upon something related to this in the last few days, I'll try to find it again and see if it's applicable here.

Sorry for the long reply; my knowledge is very limited, but I'm trying to make it as easy as I can for you.

Thanks again.
Go to Top of Page

YimingChen

1669 Posts

Posted - 03/25/2020 :  11:03:10 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hi,

Because in Origin the workbook must have unique short name, the argument in Newbook Xfunction option:=lsname sets the workbook shortname which may cause name conflict so some workbook failed to generate.

I modified the script to only set workbook long name. Also I appended the root folder name as well to make it more clear. By the way, I fixed a bug in the script that causes the weird behavior ( in second loop, I falsely put n as iteration count). See if it is working now.

string strPath$ = %X%G;
path$= strPath$;
findFolders;  //  Find all Temperature XX folders. 
string froot = folder$;
int n = froot.GetNumTokens(CRLF);
string strTemp$; 
for(int ii = 1; ii <=n; ii++) 
{
	string strCurRoot$ = froot.GetToken(ii, CRLF)$;
	path$ = strPath$ + "\" + strCurRoot$; 
	findFolders;  //  Find all folders under current Temperature XX folder.
	int nn = folder.GetNumTokens(CRLF);
	string strTemp$;
	for(int jj = 1; jj <=nn; jj++) 
	{		
		strTemp$ = strCurRoot$ + "_" + folder.GetToken(jj, CRLF)$; 
		newbook name:=strTemp$; 
	}	
}


James
Go to Top of Page

Clairekun

Germany
175 Posts

Posted - 03/25/2020 :  12:00:23 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hi,

Thanks for your quick response. I guessed n was the problem; I tried to change the variable to m before posting last reply, but my brain decided to ignore jj <=n so, of course, nothing happened. As for the long/short name, that's not the problem. I actually put lsname to see if, specifying a short name (I put a different prefix per Temperature folder in the script), things would change.

Therefore, only 4 books are created. If I delete the newname bit, then, 12 new workbooks appear, which is the right result. So, a prefix before next workbook is created is the only way indeed, but I must have done it wrongly before, because I got it to work now. The code I finally have is:
string strPath$ = %X%G;
path$= strPath$;
findFolders;  //  Find all Temperature XX folders. 
string froot = folder$;
int n = froot.GetNumTokens(CRLF);
string strTemp$; 
for(int ii = 1; ii <=n; ii++) 
{
	string strCurRoot$ = froot.GetToken(ii, CRLF)$;
	path$ = strPath$ + "\" + strCurRoot$; 
	findFolders;  //  Find all folders under current Temperature XX folder.
	int nn = folder.GetNumTokens(CRLF);
	string strTemp$;
	for(int jj = 1; jj <=nn; jj++) 
	{		
		strTemp$ = folder.GetToken(jj, CRLF)$; 
		newbook name:="T"+strCurRoot$+strTemp$ option:=lsname; //first letter of short names can't be a number, so T from Temperature is added to the name.
		page.longname$ = strTemp$;
	}	
}


This way, workbooks are created with different prefixes (both short and long name) and then, I change the long name to something more manageable (I don't need the temperature there because they'll be under Temperature x folders, anyway).

This successfully creates 12 correctly named workbooks. There is only one more thing I would like and haven't been able to find out how: since there is a character number limitation to short names, they get trimmed. Can I trim everything after certain letter or number, so that the pattern is consistent? I tried using GetToken(2,'letter') to no avail. This is by no means crucial, just simple curiosity.

Edited by - Clairekun on 03/25/2020 12:04:56 PM
Go to Top of Page

YimingChen

1669 Posts

Posted - 03/25/2020 :  5:19:41 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
The shortname of workbook is limited to 12 characters. If you would like to trim to certain length, you can use string method Mid(), Left() or Right(). Check the string method page below:
https://www.originlab.com/doc/LabTalk/ref/String-obj

James

Edited by - YimingChen on 03/25/2020 5:20:01 PM
Go to Top of Page

Clairekun

Germany
175 Posts

Posted - 03/26/2020 :  05:31:26 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hmmm I'm afraid that won't do, since the same pattern doesn't imply the same length; as in, temperatures of 80K and 300K would need different trimming.

I believe an if statement could be used if I specified where the number is, but I would have the same problem since the number wouldn't always end in the same position.

Is there any workaround that you can think of?


Edited by - Clairekun on 03/26/2020 08:47:10 AM
Go to Top of Page

YimingChen

1669 Posts

Posted - 03/26/2020 :  08:48:36 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hi,

I just want to confirm that you would like to extract 100K from string Temperature 100K, right? If so, you can use GetToken() method.

string aa = "temperature 100k";
aa.GetToken(2," ")$=


For managing project explorer, we have many XFunctions. Can you check if they are useful in your case? If not, please start a new forum item, we can check further.
https://www.originlab.com/doc/LabTalk/guide/Managing-the-Project#Project_Explorer_X-Functions

Thank you
James

Edited by - YimingChen on 03/26/2020 08:48:56 AM
Go to Top of Page

Clairekun

Germany
175 Posts

Posted - 03/26/2020 :  09:01:39 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Also, I could move the newly created workbooks to the corresponding Temperature folders, I'll leave the code here in case anyone needs it (please tell me if this belongs to a new topic or even if it doesn't eblong anywhere and neets to be deleted). It is based on parts of the names which are shared for both; in my case:

Temp 1 > Time a, b, c, d.

Here, folder Temp 1 would hold workbooks a, b, c and d. The names of those workbooks have "temp 1" in them, so a condition where temp 1 = part of the workbook name is needed.

Project Explorer folders, apparently, have no predefined string; therefore, there seems to be no way to loop through them to move books to each one separately (please correct me if I'm wrong).

I found two possible solutions for this:

1. Creating the folders, selecting each one manually and moving the files. (Modify as needed)

CREATE FOLDERS BASED ON WINDOWS FOLDER NAME
string strPath$ = %X%G; //Assigns a string to current project path
path$= strPath$; //Makes that string the default path (default path is path$)
findFolders;  //  Find all subfolders in default path, which was defined above.
string froot = folder$; //Assigns a string for folder manipulation
int n = froot.GetNumTokens(CRLF); //Getes the number of folders
string newfolder$; //Creates a new string
for(int ii = 1; ii <=n; ii++) //For all folders in specified path
{
	newfolder$ = froot.GetToken(ii, CRLF)$; //Get the name of the folders which are separated by a carriage return in the explorer list
	pe_mkdir folder:=newfolder$ //Make new folders in project explorer which have the same name as the folders specified
}


MOVE FILES TO SELECTED FOLDER

doc -e W { //loops through all objects in the project (in this case, workbooks)

string wbooks$ = page.name$; //Assigns a string to workbook names
wbpart$= wbooks.mid(nfirst,ncount)$; //Gets a section of the name
string folname$; //New string for Project Explorer folder names
pe_path path:=folname$; //Assigns the selected project Explorer folder
folpart$= newname.mid(nfirst,ncount)$; //Gets a section of the name
if (wbpart$ == folpart$) pe_move move:=wbooks$ path:=folname$; //If the section of the workbook names equals the section of the folder name, move them inside
};

Use https://www.originlab.com/doc/LabTalk/ref/String-obj to find Mid object and define nfirst, ncount.

2. Do it all at once: move the files when each folder is created (Modify as needed).
string strPath$ = %X%G; //Assigns a string to current project path
path$= strPath$; //Makes that string the default path (default path is path$)
findFolders;  //  Find all subfolders in default path, which was defined above.
string froot = folder$; //Assigns a string for folder manipulation
int n = froot.GetNumTokens(CRLF); //Getes the number of folders
string newfolder$; //Creates a new string
for(int ii = 1; ii <=n; ii++) //For all folders in specified path
{
	newfolder$ = froot.GetToken(ii, CRLF)$; //Get the name of the folders which are separated by a carriage return in the explorer list
	pe_mkdir folder:=newfolder$ cd:=1; //Make new folders in project explorer which have the same name as the folders specified. Activate that folder.
	doc -e W {
		string wbooks$ = page.name$;
		wbpart$= wbooks.mid(nfirst,ncount)$;
		folpart$= newfolder.mid(nfirst,ncount)$; //Here, no new string is needed for the folders, since we already defined it above
		if (wbpart$ == folpart$) pe_move move:=wbooks$ path:=newfolder$; 
	};
	pe_cd path:="/"; //Go back to parent folder

};

Again, Use https://www.originlab.com/doc/LabTalk/ref/String-obj to find Mid object and define nfirst, ncount.

I couldn't have done this without your help, please accept my most sincere gratitude.
Go to Top of Page

YimingChen

1669 Posts

Posted - 03/26/2020 :  09:55:27 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Great! Just one thought. Can you simply repeat the following steps:
1. Get Temp XX folder name.
2. Create folder with that in PE in ORigin.
3. Go into that folder.
4. Create workbooks with name from subfolders in Temp XX folder.

Repeat this for all Temp XX folders, this way you don't have to move workbooks around.

James
Go to Top of Page

Clairekun

Germany
175 Posts

Posted - 03/26/2020 :  6:44:59 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Thank you for your help. I did what you suggested and, also, appended my impASC function and a loop over the different worksheets to add header and units. With this, only one script will get the desired folder/book structure and data.

I'll have to create a graph template to plot everything after this, but I believe I'll be able to do that by myself. And perhaps try to get book short names trimmed.

Again, thank you all and sorry for the inconveninence.
Go to Top of Page

Clairekun

Germany
175 Posts

Posted - 03/27/2020 :  04:27:52 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
quote:
Originally posted by Clairekun

And perhaps try to get book short names trimmed.



I found out what my mistake was. I was using GetToken correctly, but the string page.name$ can't be used as a variable and I was getting an error, but using %(page.name$) or %H worked.
string sname$ = page.name$; 
string trimmed$ = sname.GetToken(1,"letter")$; 
window -r %(sname$) %(trimmed$); //Here, sname$ = page.name$ = %H


So that's it, all solved.
Go to Top of Page
  Previous Topic Topic Next Topic Lock Topic Edit Topic Delete Topic New Topic Reply to Topic
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
The Origin Forum © 2020 Originlab Corporation Go To Top Of Page
Snitz Forums 2000