Consulting

Results 1 to 17 of 17

Thread: Solved: Lorem Ipsum generator

  1. #1
    VBAX Expert TrippyTom's Avatar
    Joined
    Jul 2005
    Location
    New York, NY (USA)
    Posts
    556
    Location

    Solved: Lorem Ipsum generator

    Hi everyone,

    For an exercise in learning, I thought about making a Lorem Ipsum generator like the one here: http://www.lipsum.com/

    I just want to use the first 10 paragraphs though from the Lorem Ipsum text and work with that. I presume this would involve arrays, but I'm very inexperienced with arrays. Does anyone have a good suggestion on how I should approach it?
    Office 2010, Windows 7
    goal: to learn the most efficient way

  2. #2
    Knowledge Base Approver VBAX Master Oorang's Avatar
    Joined
    Jan 2007
    Posts
    1,135
    Location
    Put the whole text as a string constant. For letters use mid. For words, load the string into a byte array and loop through it counting spaces to get the position of the correct break, then use mid again. For sentences do the same but count periods. For paragraphs count line breaks. (Make sue you put line breaks into the constant.) For lists prepend the constant with bullet then replace all occurances of period with period / bullet / line break, then remove the final period / bullet / line with just period.

  3. #3
    VBAX Expert TrippyTom's Avatar
    Joined
    Jul 2005
    Location
    New York, NY (USA)
    Posts
    556
    Location
    Can I have that much text as a constant? Is there no maximum character limit (like 255) or something?
    Office 2010, Windows 7
    goal: to learn the most efficient way

  4. #4
    Knowledge Base Approver VBAX Master Oorang's Avatar
    Joined
    Jan 2007
    Posts
    1,135
    Location
    Short answer.... Yes.
    The only limit to a constant is the limitations of the constant datatype. A VB string has no limit but the machine it is on. The minimum memory for Win XP is 256 MB. The average PC now has at least 1GB of RAM. However assume you wanted to by polite and keep it under 10KB. 10KB is 10,485,760 bytes. A VB string 6 byte plus 4 bytes for every character. So subtract 6 and divide by 4 and you end up with 2,621,438 characters. The KJV New Testament has 179,011 words. The average word in the english language is 7 characters. Add 1 for spaces and you and up with 1,432,088 characters. There are 7957 verses, so assume an average of 5 punctuation characters per verse so that adds 39785 characters for a total of 1,471,873, and you are still haven't hit the limit.
    So uh yes, I think Lorem Ipsum will be alright

  5. #5
    VBAX Expert TrippyTom's Avatar
    Joined
    Jul 2005
    Location
    New York, NY (USA)
    Posts
    556
    Location
    Hmm, I must be doing something wrong then. I used & vbcr after every paragraph and my messagebox is showing me it's stopping at a point (see image).
    Office 2010, Windows 7
    goal: to learn the most efficient way

  6. #6
    Knowledge Base Approver VBAX Master Oorang's Avatar
    Joined
    Jan 2007
    Posts
    1,135
    Location
    Ah well THAT is a limitation of the MsgBox function. It displays up to 1023 characters. You can set a reference to the windows scripting host and use the popup method for larger text.

    The Article Below uses late binding.
    http://www.microsoft.com/technet/scr...5/hey0602.mspx

    Here is how to do it with early binding:
    Set reference to Windows Script Host Object Model (wshom.ocx), then:
    [VBA]Sub Popup()
    Dim Shll As WshShell
    Dim Msg As String
    Msg = VBA.String$(1023, ".") & "X"
    MsgBox Msg
    Set Shll = New WshShell
    Shll.Popup Msg
    Msg = Msg & Msg & Msg & Msg
    Shll.Popup Msg
    End Sub[/VBA]

  7. #7
    VBAX Expert TrippyTom's Avatar
    Joined
    Jul 2005
    Location
    New York, NY (USA)
    Posts
    556
    Location
    Ok, well I was just using the MsgBox for testing. Ideally, I would like to direct the result into a text box on my userform so the user can copy/paste it. Will this have the same limitations?
    Office 2010, Windows 7
    goal: to learn the most efficient way

  8. #8
    Knowledge Base Approver VBAX Master Oorang's Avatar
    Joined
    Jan 2007
    Posts
    1,135
    Location
    Which textbox control are you using?

  9. #9
    VBAX Expert TrippyTom's Avatar
    Joined
    Jul 2005
    Location
    New York, NY (USA)
    Posts
    556
    Location
    I'm not sure what you mean
    It's just a normal TextBox control from the userform toolbar.
    I set WordWrap to TRUE and Scrollbars to VERTICAL.
    Office 2010, Windows 7
    goal: to learn the most efficient way

  10. #10
    Knowledge Base Approver VBAX Master Oorang's Avatar
    Joined
    Jan 2007
    Posts
    1,135
    Location
    I have not hit a limit on the text box yet. But to give you a more defined answer I would need to test it's performance out. Some controls really bog on a lot of date (like the list view). Might be fun to see how your program does with textbox.value vs a label.caption.

    I suppose worstcase you could use and embedded worddoc. But I suspect you will be fine with a textbox

  11. #11
    VBAX Expert TrippyTom's Avatar
    Joined
    Jul 2005
    Location
    New York, NY (USA)
    Posts
    556
    Location
    Here's what my userform looks like. My code is in the very beginning stages - I just have to figure out the parsing now (the hardest part of course). hehe
    Office 2010, Windows 7
    goal: to learn the most efficient way

  12. #12
    Knowledge Base Approver VBAX Master Oorang's Avatar
    Joined
    Jan 2007
    Posts
    1,135
    Location
    hehe.. I love it

  13. #13
    VBAX Expert TrippyTom's Avatar
    Joined
    Jul 2005
    Location
    New York, NY (USA)
    Posts
    556
    Location
    Ok, I figured out how to do letters. Now I was wondering if you could explain a byte array so I can tackle Words. Once I figure that out, I'm sure the transition to Sentences and Paragraphs will be easy.
    Office 2010, Windows 7
    goal: to learn the most efficient way

  14. #14
    Knowledge Base Approver VBAX Master Oorang's Avatar
    Joined
    Jan 2007
    Posts
    1,135
    Location
    Byte arrays are fairly simple. It is just what it sounds like, an array of numbers which are typed a "Byte" (compare to Long Array, String Array, etc) If you do this:[vba]Dim MyByteArray() As Byte
    Const MyTestString_c As String = "Test"
    MyByteArray = VBA.StrConv(MyTestString_c, vbFromUnicode)[/vba]Your string will be put into the byte array. Now how to read it? Each element will be the ASCII Value of it's corresponding Character. Therefor MyByteArray(0) = 84 which is the ASCII value for "T", MyByteArray(1) = 101 etc. (see http://www.asciitable.com/ for the codes). So you can quickly count spaces like so:[vba]Function CountSpaces(Value As String) As Long
    Dim MyByteArray() As Byte
    Dim Char As Long
    Dim Counter As Long
    Const LowerBound As Long = 0
    Const Increment As Long = 1
    MyByteArray = VBA.StrConv(Value, vbFromUnicode)
    For Char = LowerBound To UBound(MyByteArray)
    If MyByteArray(Char) = vbKeySpace Then Counter = Counter + Increment
    Next Char
    CountSpaces = Counter
    End Function
    [/vba]
    There are many other ways to do this as well, but as you get into heavy duty string manipulation, VBA gets a little slow, and byte arrays are quite fast.


    *Note: If you want to get really fancy, I believe you can replace [VBA]If MyByteArray(Char) = vbKeySpace Then Counter = Counter + Increment[/VBA]with [VBA]Counter = Counter - (MyByteArray(Char) = vbKeySpace)[/VBA] For a performance gain.

  15. #15
    VBAX Expert TrippyTom's Avatar
    Joined
    Jul 2005
    Location
    New York, NY (USA)
    Posts
    556
    Location
    Wow Oorang, I think this is going to take me a while to digest, but I don't see where you're calling the function. I presume I would put that somewhere after the MyByteArray = VBA.StrConv(MyTestString_c, vbFromUnicode) line?

    Here's my code so far:
    [vba]
    Private Sub btnGenerate_Click()
    On Error Resume Next
    Dim Shll As WshShell
    Dim Msg As String
    Msg = "Lorem ipsum dolor sit amet, ..."

    'Set Shll = New WshShell
    'Shll.Popup Msg
    '----- Letters -----
    'tbResult.Value = Mid(Msg, 1, tbNumber)
    If optParas = True Then
    '----- Paragraphs -----
    'call Function for Paragraphs
    ElseIf optSentences = True Then
    '----- Sentences -----
    'call Function for Sentences
    ElseIf optWords = True Then
    '----- Words -----
    Dim MyByteArray() As Byte
    'Const MyTestString_c As String = "Test"
    MyByteArray = VBA.StrConv(Msg, vbFromUnicode)
    tbResult.Value = Mid(Msg, 1, CountSpaces(tbNumber.Value))
    ElseIf optLists = True Then
    '----- Lists -----
    'call Function for Sentences
    End If

    Msg = Empty
    End Sub
    [/vba]
    Last edited by TrippyTom; 06-06-2007 at 10:25 AM.
    Office 2010, Windows 7
    goal: to learn the most efficient way

  16. #16
    VBAX Expert TrippyTom's Avatar
    Joined
    Jul 2005
    Location
    New York, NY (USA)
    Posts
    556
    Location
    Ok, I think I figured out how to adapt your code to mine:
    [vba]
    ElseIf optWords = True Then
    '----- Words ----- (count spaces)
    Dim CountSpaces As Long
    Dim MyByteArray() As Byte
    MyByteArray = VBA.StrConv(Msg, vbFromUnicode)

    Dim Char As Long
    Dim Counter As Long
    Const LowerBound As Long = 0
    Const Increment As Long = 1
    For Char = LowerBound To UBound(MyByteArray)
    If MyByteArray(Char) = vbKeySpace Then Counter = Counter + Increment
    CountSpaces = Counter
    If CountSpaces = tbNumber Then Exit For
    Next Char
    tbResult.Value = Mid(Msg, 1, Char)
    [/vba]

    Thanks so much Oorang!!!
    Office 2010, Windows 7
    goal: to learn the most efficient way

  17. #17
    VBAX Expert TrippyTom's Avatar
    Joined
    Jul 2005
    Location
    New York, NY (USA)
    Posts
    556
    Location
    I don't think I'm adding the new lines into my constant properly.
    I'm using:
    [vba]
    msg = "...sollicitudin. " & vbCr
    Msg = Msg & "Suspendisse ..."
    [/vba]

    But it's not finding the return. How would I insert a carriage return into my constant correctly? Looking at the ASCII table you posted a link to, it looks like it might be code 13... but I'm not sure.

    [edit] -- I figured this part out.
    Office 2010, Windows 7
    goal: to learn the most efficient way

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •