Tools, Techniques, and Training for Nirvana Platforms |
OmniTrader, VisualTrader, OmniFunds & OmniVest |
| ||
| ||
|
|
Psalm 128:1-2 (NKJV) … Blessed is every one who fears the Lord, who walks in His ways. When you eat the labor of your hands, you shall be happy, and it shall be well with you. |
DotNet File Date Time String Etc Func's | |||
|
JimDean |
| ||
Owner/Admin Posts: 3925 Location: USA: GA, Lawrenceville | This thread has really valuable info, for "hard-core" OLang-coders ... Occasionally I find a need to do something with strings or dates & times or files, etc. Usually, solving this "the first time" involves some research (dotnet vba subject googling) and considerable experimentation to find out which of the dotNet (vba) methods and objects etc are supported by OmniLanguage (that is, whether the parser rejects their syntax or not). This thread's purpose is to record these odds and ends as I find them. I'm setting this up as a "frozen" thread (ie no discussion), to keep it clean as a reference. Feel free to post questions on another thread ... if you do, please include a link to whatever specific post in this thread that you're referencing. The syntax for a link to *this* post: http://tradetight.org/forums/thread-view.asp?tid=1449#M9753 ... the 9753 comes from the "Posted" caption at the top of the post, and the main part of the string is copied from the browser's URL field ... you need to specify "#M" before the post-number ... you can if you wish remove anything after the ".asp?" then tack on the "#M1234" | ||
JimDean |
| ||
Owner/Admin Posts: 3925 Location: USA: GA, Lawrenceville | Creating File Folders When you work with files in OLang, it's important to understand that the STARTING path-location which OLang presumes (for OT2019) is "C:\Program Files (x86)\Nirvana\OT2019\". So, if you want to access a file in that folder, you don't need a path, just the filename & extension. Since virtually all of my work with files is oriented around the SDK (where custom DLL's reside), the normal starting-point path that I use is: "C:\Program Files (x86)\Nirvana\OT2019\SDK\". Usually I assign that to a string-variable: dim FPath as string = "C:\Program Files (x86)\Nirvana\OT2019\SDK\" To keep files manageable, it's smart to create a "folder tree" that holds different kinds of files in different places ... this promotes "good housekeeping" and reduces confusion and mistakes. For my TradeTight development work, I've set up a few big-category folders inside the SDK to hold Support files, Output files, and so on. Of course, you can do this manually via Windows Explorer ... but if you want to do it via OLang, you need to take care not to generate errors, since OLang doesn't support "on error goto" or "try" syntax to capture boo-boos. Let's make this fun ... let's create a TWO-LEVEL TREE all at once. That is, presume the SDK folder currently has no folders inside it. The task is to create a subfolder "TT_Output-Files" ... and also create a sub-subfolder "Stradicator-TradeLogs" inside that subfolder. Before you try to create folders, you should first check to find out what exists, so that you don't get hit with a Runtime Error. In this case, what we need to do is: 1. define the FULL PATH into the deepest-level new folder, starting from a KNOWN location 2. then TEST that new path to make sure it doesn't already exist, using "dir(path,vbDirectory)" 3. then go ahead and CREATE the new path using "mkdir()" dim FPath as string = "C:\Program Files (x86)\Nirvana\OT2019\SDK\" dim NewPath, Mpt as string ' I use Mpt to hold a null-string, for clarity ... default Mpt="" NewPath = FPath & "TT_Output-Files\Stradicator-TradeLogs" if dir(NewPath, vbDirectory) = Mpt then mkdir(NewPath) ... the result of this is that the mkdir command CREATES not only the TT_Output-Files folder (if it didn't already exist) ... but also creates the "Stradicator-TradeLogs" folder inside it. ... interesting note ... sometimes OLang code, when copied to RTF files and back again, will weirdly "lose" the backslash character in some places. So, it may be helpful to note that for purposes like defining paths, you can alternatively use the "/" forward-slash character instead, interchangeably. That's not "standard" Windows syntax, but hey it works. If you want to know more about this stuff, use your browser to google something like "dotnet vba mkdir" or "dotnet vba vbDirectory", etc ... always choose the Microsoft Docs links to avoid nonsense and viruses. You'll either be utterly confused by what you find ... or you'll discover a whole new world of "fun" ... and likely burn up a lot of time "experimenting" and learning. Enjoy! | ||
JimDean |
| ||
Owner/Admin Posts: 3925 Location: USA: GA, Lawrenceville | Checking or changing the DateTime stamp of a file ... Presume the file path has been saved in the FPath variable (see prior post), and that the existing filename you want to work with is "TestFile.txt". You can check the last-modified time of an existing file by using something like this: dim S1 as string S1 = System.IO.File.GetLastWriteTime( FPath & "TestFile.txt" ) debugmsg(D1) ... this will return something like: "10/13/2019 7:05:16 AM" in the Debug pane of the OLang editor If you'd like to CHANGE that datetime stamp to something different, just use this command: System.IO.File.SetLastWriteTime( FPath & "TestFile.txt", "09/3/2020 1:23:04 PM" ) ... follow that with the prior "S1 =" and "debugmsg" lines, and you'll see the timestamp has changed. Note that you DO have to include the "System.IO." portion in these commands ... you can't just use "GetLastWriteTime()" by itself. | ||
JimDean |
| ||
Owner/Admin Posts: 3925 Location: USA: GA, Lawrenceville | If you want to do some fancy-formatting of datetime (or other) string info, you can use the "ToString(format)" method ... also, you can change capitalization with ToUpper() or ToLower(): dim S1, S2, S3 as string S1 = now S2 = now.ToString("ddMMMyy") S3 = S2.ToLower() debugmsg(S1&" > "&S2&" > "&S3) ... in the debug pane, you'll see something like: 10/13/2019 9:43:24 AM > 13Oct19 > 13oct19 Here's another nuance ... the above example uses string variables for everything ... but the "tostring" method requires that the variable "type" be specific to what's being done to it (my unofficial explanation ... ref Microsoft docs for full info). OLang allows a variable to be declared as "datetime" ... which is the "native" form of the "now" function. So ... dim S2, S3 as string dim DT as datetime DT = now S2 = DT.ToString("ddMMMyy") S3 = S2.ToLower() debugmsg(DT&" > "&S2&" > "&S3) ... produces the same output in the debug pane that the earlier snippet does: 10/13/2019 9:43:24 AM > 13Oct19 > 13oct19 (note that in the first example, if you wrote S2 = S1.ToString("ddMMMyy") then an error is gen'd, since S2 is a string variable as opposed to a datetime variable. Click here for a complete list of all date and time custom-formatting string identifiers. | ||
JimDean |
| ||
Owner/Admin Posts: 3925 Location: USA: GA, Lawrenceville | Basic String manipulations ... I'm just going to mention these quickly without much explanation, since they've mostly been around since good old DOS Basic back in the 80's. Main reason for this post is to point out that they work in OLang, and the necessary syntax to use. Grab two right or five left characters of a string: right(S1,2) left(S2,5) ... if the string is shorter than 2 (or 5), these still work okay Grab third and fourth character of a string: strings.mid(S1,3,2) ... prep by assuring the string is at least 3 char's long, else error Find what location "x" is at, inside another, starting from char #5: instr(2,S1,"x") ... this returns zero if "x" is not in S1 ... err's if string is <5 char's Replace a portion of a string with something different: replace(S1,"xy","abc") ... if S1=123xy45xy, this changes it to 123abc45abc Find the length of a string: N1 = len(S1) Find a character from its Ascii code: S1 = chr(32) '... ascii 32 is a space Find and ascii code from a string-character: N1 = asc(S1) '... assigns 32 to N1 Convert a string to upper or lower case: ucase("Abc") ... lcase("BcA") Remove excess spaces from a string's beginning, end or both: Ltrim(S1), Rtrim(S1), trim(S1) Create a repetitive-character string: strdup(12,"x") ... results in "xxxxxxxxxxxx" | ||
JimDean |
| ||
Owner/Admin Posts: 3925 Location: USA: GA, Lawrenceville | Basic file access stuff ... Reading and writing files in OLang can be a real PITA, since only a handful of the many dotNet file-IO methods are supported ... and the support of them is sort of willy-nilly. The other big danger in attempting OLang File-IO is the absence of error-trapping capabilities such as "on error goto" or "try catch". Therefore, the OLang coder must be *very careful* to baby-step into this process, and assure all necessary steps are taken to prevent errors. With that in mind, this post just lists "viable syntax" for File-IO related commands ... I'm not going to give complete examples ... if you don't know how to work with this, or don't have the patience to experiment, then it's best NOT to mess with it. These examples use a "StreamWriter" approach ... older syntax that uses "#1" filenumber-type reading and writing works too, but it's more awkward and pretty outmoded. Note that only a small subset of all the StreamWriter library stuff seems to work from OLang. You've been warned ;~) 1. When working with files, you need to dimension their containers as "objects": dim ReadFyl, WrytFyl as object 2. You can Open an existing file for sequential Reading ... and ALWAYS ALWAYS be sure to CLOSE the file after you're done using it ... while in the same routine ... presume Line and PathName below are dim'd as string variables ... this code reads the first line (record) of the file, then closes the file: ReadFyl = My.Computer.FileSystem.OpenTextFileReader( PathName ) Line = ReadFyl.ReadLine() ... do something ... (maybe put a loop around the Line= command) ReadFyl.Close 3. You can Create and Open a new file for sequential Writing ... a particular file can only be open to Read or to Write at any given time (not both at once) ... again, ALWAYS ALWAYS be sure to CLOSE the file after you're done. The second parameter is important: WrytFyl = My.Computer.FileSystem.OpenTextFileWriter( PathName, false ) WrytFyl.WriteLine("this string becomes a new record in the file") ... do something ... (maybe put a loop around the WrytFyl.WriteLine command) WrytFyl.Close 4. You can Append more lines to an existing file, by using the code above, but with the second parameter as "true" instead of "false" 5. Don't try to read past the end of file, especially if you're using a Loop. Normally, that loop also will contain a test to see if you "found" the Line you were looking for ... when you do, the Exit Do command jumps out of the loop efficiently. You can test for the end of file in a reading-loop using: Do Until ReadFyl.EndOfStream Line = ReadFyl.ReadLine() ... code that works with Line if DoneCondition = true then Exit Do Loop ReadFyl.Close 6. Before trying to Write to a file, or Rename it, or Copy it, or Kill it ... it's best to make sure it doesn't have some kind of limiting-attribute that would prevent the operation and throw an error. So, it's good practic before opening a file for writing, or manipulating the file, to use: SetAttr( pathandfilename, vbNormal ) ... here are commands to rename, copy or kill a file (wildcard characters are NOT allowed) ... My.Computer.FileSystem.RenameFile( pathandfilename, newfilename ) My.Computer.FileSystem.CopyFile( pathandfilename, newpathandfilename) Kill( pathandfilename ) *** ALWAYS check for file existence before reading or writing, to prevent errors from occuring *** Before reading or appending, use Dir() command (see earlier post) to check that the file exists Before Opening a New file for writing, use Dir() to check if the path does, but file *doesn't* exist | ||
JimDean |
| ||
Owner/Admin Posts: 3925 Location: USA: GA, Lawrenceville | Checking all the files in a folder ... In this case, I'm just showing a snapshot of some sample code. This creates a popup box that lists all the text-files in the Fpath folder. Note that: FPath needs to be dim'd as string and assigned ahead of time to a falid Path CurFyl, Msg, S1 & S2 need to be dim'd as string AllFyls needs to be specifically defined as: dim AllFyls as object = CreateObject("Scripting.FileSystemObject") Here is the code, without the pretty-printing in the snap: if AllFyls.FolderExists(Fpath) then AllFyls = System.IO.Directory.EnumerateFiles(Fpath, "*.csv") S2 = "" for each CurFyl in AllFyls S1 = CurFyl.Substring(Fpath.Length) S2 = S2 & vbLF & S1 next Msg = " '.TXT' files available in '" & Fpath & "' folder:" & vbLF & S2 else Msg = "PROBLEM! ... the ' " & Fpath & " ' folder Does Not Exist!" end if MsgBox(Msg) (List All Files in Folder.png) Attachments List All Files in Folder.png (12KB - 3 downloads) | ||
|
Owner of site: Jim Dean -- Forum content is confidential, and may not be distributed without written permission. | |