• PrivateProfileString Limit?

    Author
    Topic
    #357417

    Does the privateprofilestring command have a limit on the length of the string it can write?

    I’ve got an ini file entry that needs to be up to 700 characters long, but privateprofilestring writes only 253 chars.

    If this is the limit, is there an alternative?

    Viewing 4 reply threads
    Author
    Replies
    • #530929

      Kevin,

      Congratulations on your new ribbon.

      Alternatives might be:
      .Split the string into 3
      .Write your own ini file read/write. Nit all that hard to do- though I haven’t done that for a while. Chris might have aomething- check the archive
      .Look at API calls

      • #530930

        Geoff,

        Thanks for the ‘grats.

        I’ll investigate these. Chris, same me some hog nosing and post me what I need!

        • #530932

          Maybe a start in this thread?

          • #530990

            Yabbut “this thread” is horribly convoluted. I think it’s a classic case of the argument for sumamrizing a thread to see if there’s any part that has redeeming social value. I just went had a look, and I’m either ashamed or terrified. Either way I’m not coming out from under the bed for a while …

            • #530996

              [indent]


              Either way I’m not coming out from under the bed for a while …


              [/indent]Is that a promise? grin

          • #531036

            Gee Wiz, GW, look at that thread!

            I guess when you offer a premium or prize for solving problems you get lots of attention. That Stever G. has got us pegged.

            I look forward to reading the whole thing. And it looks like the topic might have some code I’m been looking for for my “imitate recents” list. Thank you!

        • #530988

          >same me some hog nosing

          So it’s the same old Kevin-the-hog, eh? Oh well ….

          You want the good news or the bad news?

          Good: I decided to pull the INI routines out of my utils.dot and post them on the web in full source regalia.
          Bad: I haven’t posted them yet.
          Good: I cleaned them up, streamlined them
          Bad: The 255/256 limit got me to thinking of a neat way to circumvent that while still making use of the apiPutPrivateProfileString and apiGetPrivateProfileString functions.
          Good:The new code has luvverley test examples, better than the usual stuff I post.
          Bad: Today I drive out the east end to install a new computer for a sweet little old lady …..
          Good: I loves ya almost as much as I love the LOL, so I’ll get onto it as soon as I return home, truffles.

          • #531045

            Chris,

            You are either a briliant guy or an average guy with a bunch of loose screws. I can’t decide.

            What is “luvverley”? An adjective? A lunar landing module? Canadian for “home plate”?

            I hope the little old lady appreciates how much trouble she’s causing me while you abandon your comrades in need.

            • #531093

              > You are either a briliant guy or an average guy with a bunch of loose screws.

              Let’s see, it’s Wednesday, so the answer is …

              Luvverly, as in My Fair Lady, well before your time, my son (vbg)

              OK. I have built a page here with my current code. This version allows you to switch environments via the INI file itself, heh heh.

              On the way home I worked out how to get around the 255 limit imposed by APIProfile string without the user (that’s us VBA coders) needing to know about. I’m a transparent sort of guy.

              HOWEVER I don’t get to be brilliant until well after Sundown on Wednesdays, so the code won’t be available until tomorrow. I’ll post here when it’s up.

              You guys looking at mars these nights?

        • #531162

          Here’s a FIRST DRAFT. It’s not finished, but as usual I invite comments.

          I was going to add a test to my strGP and strPP functions: ” If the string is at or near the 254 limit, call my addon routines”, but then I thought, why not rewrite the APIProfile stuff anyway. I don’t spend a lot of time in grabbing environment stuff, and I write MUCH better code than Bill. For example, I’m actually trapping every error I can think of and assigning a numeric code (intResult) which *I* throw away, but youse coould retain to raise an Error.

          It strikes me that i should maybe rewrite all this as a CLASS object anyway, and treat my INI file as an Obkect of some sort that holds “interesting stuff”, and have methods like .Get and .Put, and have properties like .OriginalString and .ErrorCode.

          I should probably go back and reread the ApiGet and APIWrite headers to make mine correspond exactly to theirs.

          I have to get back to work. I’ll clean this code up and add useful modifications, and then post it on my web site.

          Must admit, it’s sumpn’ else to see my screen fill up with a MsgBox window from ONE INI file key!

    • #531112

      Kevin,

      Might you consider using the Scripting Runtime library, which has a nice text file handling objext called Textstream in addition to File handling functions.

      The following sample code writes a string of 1000 characters +

      Sub WriteToINI()
          Dim fso As Scripting.FileSystemObject
          Dim txtOut As Scripting.TextStream
          Set fso = New FileSystemObject
          Set txtOut = fso.CreateTextFile("D:TextStreamINI.txt")
          For i = 1 To 100
              TestStr = TestStr & "0123456789"
          Next i
          With txtOut
              .Write "[Heading]" & vbCr
              .WriteLine "Test1= " & TestStr
              .WriteBlankLines 1
              .WriteLine "Test2= " & StrReverse(TestStr)
          End With
          Set tsOut = Nothing
      End Sub 

      It is only a sample, and shows what be done if you can utilise the above library.

      Andrew C

      • #531113

        Andrew,

        That’s an excellent idea. Where do you get your info on the Scripting library? I never consider FSOs because I have no help file or tutorial on the object model.

        I’ve got to learn more about it. Thanks much.

        • #531145

          Hi Kevin,

          If you’ve still got Office 97, then you either do or don’t have MS Scripting Runtime – depends on what other components may have gotten installed. A look at Tools>References will reveal.

          An eye-opening intro to working with text files using FSO, can be found in a recent article by Peter Aiken in MS Office Pro magazine. The article can be accessed online here – but you do need a subscription to the magazine (or a trial subscription) to access the article. (I don’t know what it says about me, that spying a new issue of this mag in my mailbox elicits the same kind of enthusiasm I used to feel when a new issue of Surfer arrived!)

          Gary

          • #531146

            Even if you don’t have a reference set, you may have and “scrrun.dll”.

          • #531207

            >>(I don’t know what it says about me

            It says that you are one knarly dude and I’m in the right place.

        • #531156

          Kevin,

          Info on Scripting Library from MSDN Online

          Of course Geoff’s suggestion might suit you better, but I assumed you might not have wanted that method for some reason.

          I would personally prefer the FSO and Textstream objects for reading ASCI files, but that’s just my preference.

          Apart form FileSystem and Textstream objects, the SRL also includes a Dictionary object , which enables you to set up collection like objects, but I have never really explored it (yet). The following is one discription from MS :
          [indent]


          A Dictionary object is the equivalent of a PERL associative array. Items, which can be any form of data, are stored in the array. Each item is associated with a unique key. The key is used to retrieve an individual item and is usually a integer or a string, but can be anything except an array


          [/indent]Seems like a nice toy for Chris Greaves

          Andrew

      • #531147

        Andrew,

        While I have used FileScriptingObject for things involving directory checking, date/time stamp processing etc, I can’t see from your example why it is needed.

        Would the following achieve the same?

        Sub WriteToINI()
         Dim i As Integer
         Dim TestStr As String
         Dim iFileno As Integer
         
            iFileno = FreeFile
            For i = 1 To 100
                TestStr = TestStr & "0123456789"
            Next i
            Open "D:TextStreamINI.txt" For Output As #1
            Print #1, "[Heading]" & vbCrLf & _
                "Test1= " & TestStr & vbCrLf & _
                "Test2= " & StrReverse(TestStr)
            Close #1
        End Sub

        Of course, you may well be leading further…

        Also, I suspect you have not used “Option Explicit”- I suspect the “Set tsOut = Nothing” should be “set txtOut = Nothing”.

        • #531160

          Hi Geoff,

          I suppose the FSO/Textstream is not needed, but I just prefer it for text files, especially for reading them.

          You are of course right about Option Explict – I have it on be default, but sometimes switch it off, which I must have done. Excuse – I don’t have a good one, but it was late.

          It should of course end with :-

          	Set txtOut = Nothing
          	Set fso = Nothing

          Amdrew C

          • #531165

            Not a worry, Andrew,

            Congratulations on your new ribbon, by the way. You’ve really earned it. I think that there’s many people out there who have been grateful for the frequent and useful help you have provided.

            OK, I was digging for something, and I did not make it explicit.

            I was wondering if using the filescriptingobject might make it easier to interpret the incoming text file- or something like that. By “casting aspersions” on using fso for a plain “file write”, I guess I was hoping you could provide some other reasons where it could be useful, over and above a simple file I/O.

            There are obviously objects provided to you which make some things more readable- but are there other things in the object model which can make it more powerful?

            Sorry, I’m just trying to learn….

            • #531197

              Thanks Geoff,

              I just prefer to use it, as it is more VB(A) like than the more traditional method. I also prefer it for reading text files, as you can start reading a line from any character position you like, which makes reading fixed width fields from a file very easy, and that I find useful.

              As i also prefer the FileSystemObject for other file handling I just tend to use both of the objects provided. And it means less chance of using #2 instead of #1

              It is not much use when it comes to binary files however.

              Nothing really special Geoff, just a preference

              Andrew

      • #531170

        Andrew, like many others, I’ve not used the Scripting Library. From the example you gave, it seems to be more work than issuing a series of Print commands (for CRLF-line based text).

        Is that view correct? (I hope so)

        Having said that, there must be something REALLY different about the Scripting Library that makes it more than just a straight substitute for the Print command.

        I should go read the references you provided, right ? (grin!)

    • #531532

      Your upgraded functions are ready via my web site.

      I rewrote the basic long-string functions to conform to the published (ApiGuide) descriptions:

      Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" _
        (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpString As Any, _
        ByVal lpFileName As String) As Long
      
      and
      
      Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" _
        (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, 
        ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long
      

      My syntax is thus:

      Public Function GetLargePrivateProfileString(ByVal lpApplicationName As String, _
        ByVal lpkeyname As String, ByVal lpDefault As String, lpReturnedString As String, _
        ByVal nSize As Long, ByVal lpfilename As String)
      
      and 
      
      Public Function WriteLargePrivateProfileString(ByVal lpApplicationName As String, _
        ByVal lpkeyname As String, ByVal lpString As String, ByVal lpfilename As String) As String
      

      I’m a little puzzled over the API description of the returned string from the Get call. It is declared as a ByVal and that doesn’t work for me in Word97SR2/VBA (ByVal lpReturnedString As String) unless I’m missing something in “lp” as Long Pointer. Comments welcomed. When I used a ByVal I got an empty string back each time. When I removed the ByVal I got results (There’s a good joke in there about Shell functions and ByValves, but I’m above that sort of thing!)

      Having written my “large” equivalents of the API functions, I rewrote the strGPA and strPPA cover functions to use the new Large instead of the standard functions. In theory, nothing in my utilities and applications need change. I wrote a slave function “Public Function strGetEnvironmentFileName(strApplication As String)” to deal with switching INI files through themselves. I want to do this so that I can process a client set of documents with a different INI file from another client set. The INI file holds the name of the rules table, so I need those separate INI files.

      The cover functions strGPA and strPPA are designed for ease of use when writing an application which is probably going to be happy with one section in the INI file. The section name will be identical to the generic application name.

      • #531680

        Thanks, Chris.

        Hopefully I’ll have time to take a look at your latest handywork today.

        I’ve got something to propose to all the programmers at the lounge. Look for an upcoming post later….

        • #549638

          I found a bug in my code, fixed the bug and found another problem.

          The bug was leaving an extra chr(10) at the end of an inserted string – if you looked at an INI file with Notepad you’d see extra lozenges within the file. Fixed that, I think/hope. Testing continues.

          I ran into another problem with binary files, and am searching for a solution:

          1) I write a binary file with a string of length 22 characters

          2) I read the string back.

          3) I shorten the string to be 21 characters

          4) I write the string to position “1” in the binary file.

          I have written 21 characters to the file, but the length appears to be 22 characters, that is, it creeps up always maintaining the maximum length ever written.

          Anyone know of a way to reset the length?

          I’m currently KILLing the file prior to writing; it’s a solution but not a pleasant one.

          • #549756

            Writing only 21 characters back doesn’t delete the 22nd character that’s still there. The string length just tells it how long a record is so it knows how big a chunk to manipulate and can tell you how many records of that length there are.

            • #549800

              Thanks, Charlotte, but I’m not doing “records”; there is no concept of records in this mode, unless they are single-character records.

              Doing a binary WRITE lets me specify the starting position in the file, and the string that I pass defines the length.

              I contend that the VBA file management takes the greater of the existing file length and the sum of position-plus-string-length and makes the file be that big.

              That makes sense.

              However, in order to read back the file I need to set up a string equal in length to the length of the file, and that length, as we agree, will include any residue from earlier WRITEs that used more space than the latest.

              Since I am writing a substitute for INI file management, I can’t very well introduce spurious characters to define records, or even a sentinel to define the logical file length.

              To date the only workable solution I can see is to KILL the file prior to a WRITE.

              That works for me. I post these comments in case anyone else stumbles across the same problem. There may well be a Truncate-File command by VB69.

            • #549816

              Would starting at string position 0 (zero) help ?

            • #549825

              > Would starting at string position 0 (zero) help ?

              I’ll try, but I think the syntax requires the first position to be known as “1”.

              Even if 0-origin addressing was allowed, it wouldn’t change the main issue: the file size is the length of the longest string ever written. Bringing back the contents of the file brings back the greatest number of characters ever written.

              I’m going to post a short chunk of code to demonstrate this, later today. It will serve as a vehicle for testing other theories.

            • #549818

              I used the term loosely, but that’s still what it amounts to. The string you pass determines the size of the chunk you’re working with, it doesn’t change the size of the file. All you’re saying is “put this many characters back into the file at this position”. It doesn’t do anything to characters already there and outside that string length.

            • #549826

              > it doesn’t change the size of the file

              I beg to disagree.

              No, I GROVEL (grin!)

              If the file is 200 bytes long and you write a string of 220 characters, the file size changes to be 220 bytes long.

              Writing a string HAS to change the file size whenever the string being written is longer than the current length of the file.

              Reminds me of the “maximum” thermometers in the weather stations in the wheatbelt; they had a little dumbbell thingo inside the mercury tube, and the dumblell thingo lodged at the highest point ever reached by the mercury. Until it wa sshaken down, which is what happens when I kill the file.

              I’m going to post a testbed vehicle later today.

            • #549914

              done here

            • #549953

              Yes, Chris, of course writing a longer string changes the size of the file. I was talking about writing a shorter string, which is what you are doing. You aren’t replacing a longer string with a shorter one, you’re replacing a portion of the longer string with the shorter one. That *doesn’t* change the size of the file.

              The length of the string you retrieve and the length of the string you write into the file don’t necessarily have anything to do with each other. You selected 22 characters but you only wrote 21 back to the file. That doesn’t change the fact that file contains a 22-character string, it just means you overwrote the first 21 characters.

    • #549875

      hello Loungers exclamation

      PrivateProfileWhat? …[searches MSDN]… I had to look that one up. hmmn… veddy interesting. I guess I should change my name from VBNerd to VBIgnorant. grin

      Argh, I just finished an Excel application that remembers some settings in a file. I just used the FSO towrite/read the file.

      Earlier this year I attended some free MS lectures/seminars/classes on XML. One of the applications that was recommended for XML was replacing INI files with XML files. INI files aren’t that hard to read, but I guess using XML would standardize the format and allow other applications if needed to be able to read and write these files. The problem is that you need to reference another DLL in your projects and reading/writing an XML file is a little tricky. Maybe it’s a little too bleeding edge and future versions of WIndows & Office will make this easier. I didn’t do it in the Excel application because I didn’t want to have to install anything on the user’s PC.

      Have any of you used XML to read/write your files with app settings? What’s your experience with it?

      • #549882

        I’m very much interested in the XML approach. I have no experience with it yet. Is there a site or two you gleaned from the seminars you could pass on?

        Does the XML file approach require an IIS? I suppose that’s ok, maybe it’s even ideal. My next approach was to try moving ini files into SQL tables and use html to store and retrieve the values. But now that you mention this, I’d like to know more myself.

        Another dll is probably no problem since it is most likely already installed with the OS or with IE. I’m coming around to the idea that making API calls from VBA apps is preferred over native VBA object manipulating mainly due to the fact that VBA objects are often limited versions of the “real” thing. Common dialogs come to mind as well as a host of other functions like those needed to reliably test for a network or internet connection.

        If you pursue this, start a new thread. You might be on to something significant…

    • #564719

      Yo Dude!

      I’m modifying my long-string INI routines to deal with null section names (strSectionName=””) and non-existent section names. That means I can dabble in Config.SYS files as well as VB6 project files (*.VBP).

      Have you (or anyone) any idea on the maximum length of a string in Word97SR2/VBA?

      My biggest INI file is “f:program filesinstallshieldprogramfuncwiz.ini”, which occupies 212,188 bytes. I can read that into a string variable.

      For some reason I had previously set a cut-off limit of 32,767 bytes; I’m not sure why.

      • #564720

        Hey man,

        As I recall the limit is 64K, but that would not make sense if you’ve already bloated an ini to 200K+. I don’t think the FileSystemObject (being a part of the OS, not the app) has any limits. Why not start using it?

        Deeper thinkers can (and should) correct this knowledge if necessary.

        (I’m amending this post ’cause I looked in the help and found that dynamic strings can be up to 2 billion characters. Fixed-length can handle 63K. What limits exist on the ini file size, I don’t know.) You like to test stuff, open a txt file with fso and loop 2 billion characters into it and see what happens.

        • #564800

          > Why not start using FileSystemObject ?

          Lethargy. I think I’ll get this upgrade to the routines working, and THEN check out FSO. I know that a few months from now you’re going to be back with a bigger club (grin!), so go right ahead.

          I think I tried to look at FSO thre eyears back, via VBA, and didn’t have much luck (because of my poor basics in VB). You are right. i should re-investigate it.

    Viewing 4 reply threads
    Reply To: PrivateProfileString Limit?

    You can use BBCodes to format your content.
    Your account can't use all available BBCodes, they will be stripped before saving.

    Your information: