Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
melon cat
Jan 21, 2010

Nap Ghost

RICHUNCLEPENNYBAGS posted:

You can use the ROUND() function to say how many decimal places you want to go to.

=CONCATENATE(IF(E8<F8,"+",""),ROUND(((F8-E8)/E8) * 100, 2),"%")
I used your formula, and it works! Thanks for this.

ShimaTetsuo posted:

Just put the rate formula in the cell ((F8-E8)/E8) or whatever), then set the number format to "Custom", and put in something like "+0.00%;-0.00%".
Strangely, I tried using your method but Excel 2003 wouldn't round off the numbers. Not sure why. :confused:

But in either vase, I've hit another bump. I'm trying to set up the spreadsheet so the text turns red when the formula returns a -ve value, and green when it returns a positive value. But it's only showing green regardless of whether it's positive or negative:



I think the conditional formatting isn't working because Excel doesn't see it negative or positive. It sees it as a digit, and since we're concatenating a + or - symbol, it can't tell the difference. Any suggested fixes for this?

Adbot
ADBOT LOVES YOU

ShimaTetsuo
Sep 9, 2001

Maximus Quietus
I don't have a copy of 2003 to test on right now, but it definitely works in 2007.

Your conditional formatting doesn't work for the same reason I advised against the "concatenate" method: your result is not a number, it is a string, and it will not respond properly to checking whether it is positive.

What exactly does it return if you put in, say, 0.123456 in a cell, and set its custom format to:

+0.00%[Green];-0.00%[Red]

Ragingsheep
Nov 7, 2009
I've got a whole bunch of data series that I want to define as dynamic ranges. Is there anyway to quickly define them or am I stuck with doing it by hand?

Nvm, wrote my own VBA code.

Ragingsheep fucked around with this message at 03:41 on Jul 15, 2013

melon cat
Jan 21, 2010

Nap Ghost

ShimaTetsuo posted:

What exactly does it return if you put in, say, 0.123456 in a cell, and set its custom format to:

+0.00%[Green];-0.00%[Red]
This did the trick. I removed the concatenate formula and went with your alternative, modified the decimal placing, and input your Custom Format. Exactly what I was looking for. Thanks!

gandlethorpe
Aug 16, 2008

:gowron::m10:
How easy would it be to take a user-defined function that accepts two values and modify it to work with arrays? I found a great function that compares the similarity of two strings and gives it a score, but I need to compare one string and a list of strings and return the best score. Unfortunately, shift+ctrl+enter didn't work, so I must have to alter the code.

celestial teapot
Sep 9, 2003

He asked my religion and I replied "agnostic." He asked how to spell it, and remarked with a sigh: "Well, there are many religions, but I suppose they all worship the same God."
If I'm not misunderstanding you, then unless you have a shitton of rows it would be faster to just get it working with one row and auto-fill than rewrite the function to get it working with array arguments.

ShimaTetsuo
Sep 9, 2001

Maximus Quietus
He wants the function to return the best score in the list, not the list of scores.

Don't rewrite the function, just write another function that takes in one string and one array of strings, loops through the array, calling your original function on each element and keeping a running maximum.

celestial teapot
Sep 9, 2003

He asked my religion and I replied "agnostic." He asked how to spell it, and remarked with a sigh: "Well, there are many religions, but I suppose they all worship the same God."
Or =MAX() ? You'd have to use cells to store values but it would be one less UDF.

gandlethorpe
Aug 16, 2008

:gowron::m10:
Yeah, I basically wanted to take one list, apply two checks for each item on another list. The "similarity" check and a native Excel function that I normally use with ctrl+shift+enter. I ended up combining both into a new custom function.

Big Bad Beetleborg
Apr 8, 2007

Things may come to those who wait...but only the things left by those who hustle.



I have the first two columns and want to generate the second two with formulae.

ParentID:
All attachments have the word attachment in their filename, so I managed to luck into something using COUNTIF to return the value of B2 when A3 contains that string.
I've been trying for a while, but can't seem to adequately nest statements to make it check if the field above has a value. Because everything is sorted alphabetically, if the cell above is not equal to zero and the filename contains attach, the cell should be the same as the one above.
Current behaviour is to copy the ID of the previous row regardless of whether that is also an attachment or not.

AttachID:
If a document is referred to in the ParentID field of a different row, I want to list all of those ID's in the attachID field separated with a semicolon or a semicolon and a space.
This one I haven't looked at too hard, because it's meaningless without an accurate parentID column.



While I'm at it, is there a reference book or anything that someone can point me at for teaching myself this?

Turkeybone
Dec 9, 2006

:chef: :eng99:
I know this probably isn't helpful, but with IDs and such as you have them, do you think maybe you really want to use a database for this?

celestial teapot
Sep 9, 2003

He asked my religion and I replied "agnostic." He asked how to spell it, and remarked with a sigh: "Well, there are many religions, but I suppose they all worship the same God."
It looks like you're trying to normalize and map relationships but I'm not sure you're doing it the right way. Get on AIM?

Big Bad Beetleborg
Apr 8, 2007

Things may come to those who wait...but only the things left by those who hustle.

When I'm done I'll convert this stuff to a csv, import it and replace the old values with new; once that's done I won't be using the spreadsheet for anything again.

It's an unfortunate combination of bullshit software and a moron sending me poorly named files that need to made consistent with the rest of my stuff which hopefully won't occur again.

celestial teapot
Sep 9, 2003

He asked my religion and I replied "agnostic." He asked how to spell it, and remarked with a sigh: "Well, there are many religions, but I suppose they all worship the same God."
I'm pretty sure I can make this much less of a pain in your rear end, but it's going to require some back and forth. Shoot me an IM and I'll help you out.

RICHUNCLEPENNYBAGS
Dec 21, 2010
Can anyone recommend resources for learning more about VSTO? I use VBA and you can do some neat stuff with it, but VSTO seems more versatile. And the JS stuff doesn't really seem ready for primetime yet; there are a handful of things you can't do easily with VBA in it, but it's missing huge swaths of functionality VBA does have.

me your dad
Jul 25, 2006

I have a column containing email domains. I want to isolate the TLD into a column (.com, .org, and so on).

I normally do this with =mid(b2,find(".",b2)+1,3) but some of the domains have multiple periods, such as 104acv.skc.army.mil (we deal with government and military data). Another domain may only have one period like gmail.com, and another may have two periods, such as us.army.mil.

Is there a way to find the last occurrence of the period, and copy out the characters following it?

Raven31
Feb 4, 2006

me your dad posted:

I have a column containing email domains. I want to isolate the TLD into a column (.com, .org, and so on).

I normally do this with =mid(b2,find(".",b2)+1,3) but some of the domains have multiple periods, such as 104acv.skc.army.mil (we deal with government and military data). Another domain may only have one period like gmail.com, and another may have two periods, such as us.army.mil.

Is there a way to find the last occurrence of the period, and copy out the characters following it?

This solution should work.
http://stackoverflow.com/questions/350264/how-can-i-perform-a-reverse-string-search-in-excel-without-using-vba

DukAmok
Sep 21, 2006

Using drugs will kill. So be for real.

me your dad posted:

I have a column containing email domains. I want to isolate the TLD into a column (.com, .org, and so on).

I normally do this with =mid(b2,find(".",b2)+1,3) but some of the domains have multiple periods, such as 104acv.skc.army.mil (we deal with government and military data). Another domain may only have one period like gmail.com, and another may have two periods, such as us.army.mil.

Is there a way to find the last occurrence of the period, and copy out the characters following it?

If you can use VBA there's the "InStrRev" function to search from right to left.

If you need to do cell formulas, I found this one on StackOverflow that uses substitution with '|' characters to find it. Works pretty well, I modified it to work with periods instead of spaces below:
code:
=RIGHT(A1,LEN(A1)-FIND("|",SUBSTITUTE(A1,".","|",LEN(A1)-LEN(SUBSTITUTE(A1,".","")))))

me your dad
Jul 25, 2006

Thank you both - I'll give it a shot to see what I can make happen.

Edit - The formula above worked perfectly - thanks again!

me your dad fucked around with this message at 19:56 on Jul 24, 2013

ZerodotJander
Dec 29, 2004

Chinaman, explain!
Couldn't you also have just taken the last 3 characters? Something like =SUBSTITUTE(RIGHT(TRIM(A1),3),".","")

Turkeybone
Dec 9, 2006

:chef: :eng99:
So long as it wasn't some two-letter code. But you could follow that line of thought and do some string-fu to find the number of characters that come after the last "." and return them.

RICHUNCLEPENNYBAGS
Dec 21, 2010
I think it makes it much easier to just keep a UDF with regexes on-hand to solve string manipulation problems. Something to the effect of this

code:
Function RegExReplace(Original As String, MatchedText As String, Replacement As String, Optional IgnoreCase As Boolean = False, _
Optional Multiline As Boolean = True, Optional IsGlobal As Boolean = True)
    Dim Original_ As String
    Original_ = Original


Dim RegEx
Set RegEx = CreateObject("vbscript.regexp")
    With RegEx
    .IgnoreCase = IgnoreCase
    .Multiline = Multiline
    .Pattern = MatchedText
    .Global = IsGlobal
    End With

RegExReplace = RegEx.Replace(Original_, Replacement)
End Function
No, I don't think the Original_ variable is needed at all but I wrote this a while ago.

But then, for instance, if I wanted the domain of an e-mail address, I could do something like =RegExReplace(RC[-3], ".*\.(\w+)\s*$", "$1")

I have another one that uses the VBA split function, which is also pretty handy.

I'm actually curious if anyone else has any really useful general-purpose UDFs.

RICHUNCLEPENNYBAGS fucked around with this message at 02:35 on Jul 27, 2013

Ragingsheep
Nov 7, 2009
Anyone know of any good guides on PowerPivot? Like starting from the basics.

celestial teapot
Sep 9, 2003

He asked my religion and I replied "agnostic." He asked how to spell it, and remarked with a sigh: "Well, there are many religions, but I suppose they all worship the same God."

RICHUNCLEPENNYBAGS posted:

I'm actually curious if anyone else has any really useful general-purpose UDFs.

I had a great grab bag of stored procedures, but I just reinstalled Windows on my work PC and forgot to back up personal.xlsx :haw: So now I'm looking for more of these because I don't want to rewrite all that stuff. Don't be like me! Make backups!

My first order of business will be to write a macro that exports all the modules in personal.xlsx to .vb files in a github repo.

Some other good ones I had that I need to rewrite:

  • Unmerge all merged cells in a worksheet and for each merged cell copy the merge values to every cell in the MergeArea
  • Unmerge and center across the selection
  • Rename or move an open workbook
  • "Bake" conditional formatting into the cell formatting (god, that was beautiful, and such a pain in the rear end to write)
  • Some other stuff I'm not remembering

I can post these as I get them working again, or if anybody knows where similar objects have been published online I'd be grateful to be saved the assache.

celestial teapot
Sep 9, 2003

He asked my religion and I replied "agnostic." He asked how to spell it, and remarked with a sigh: "Well, there are many religions, but I suppose they all worship the same God."
One down...

code:
Sub UnMergeFill()
 '---------------------------------------------------------------------------------------
 ' Copyright : 2013-08-01
 ' Author    : celestial teapot
 ' Purpose   : remove all merged cells from active worksheet and fill values
 ' License   : MIT License [url]http://opensource.org/licenses/MIT[/url]
 '---------------------------------------------------------------------------------------
    
    Dim proc_name As String
    proc_name = "unmergefill"
    On Error GoTo ErrorHandler
    
    '''''''''''''''''''
    'Variables        '
    '''''''''''''''''''
    Dim haystack As range
    Dim oneCell As range
    Dim mrgAreaAddress As String
    Dim mrgCellCount As Long
    Dim mrgValue As Variant
    
    '''''''''''''''''''
    'Declarations     '
    '''''''''''''''''''
    Set haystack = ActiveSheet.UsedRange
    
    '''''''''''''''''''
    'Action           '
    '''''''''''''''''''
    For Each oneCell In haystack
        mrgAreaAddress = oneCell.MergeArea.Address
        mrgCellCount = oneCell.MergeArea.Cells.count
        
        If mrgCellCount > 1 Then
            With oneCell.MergeArea
                .MergeCells = False
                .Value = oneCell.Value
            End With
        End If
    Next oneCell
    
Endgame:
    Exit Sub            'Exit before error handler
ErrorHandler:
    MsgBox "There was an unhandled exception in function " _
              & proc_name & _ 
              ". Source: " & Err.Source & _
              "Error number: " & Err.Number & _ 
              " Description: " & Err.Description
    Resume Endgame
End Sub
Edit: unbroken tables

celestial teapot fucked around with this message at 00:29 on Aug 2, 2013

Requiem
Jan 29, 2003
You can't bring that weak-ass shit up in this humpity-bumpity! This ain't Club Med, baby!

Requiem posted:

Perfect, friends--it works.

Old James, please PM me contact info for PayPal?

Hi again, folks. I'm stumped again trying to combine ISBLANK and CONCATENATE. I find I'm smart enough to regurgitate your help (from June, p. 25 of this thread) but not to troubleshoot when I'm altering the context. Sorry...

Here's the formula I currently have:
code:
=CONCATENATE(A2,"<br>",L$1," ",L2,"<br>",M$1," ",M2,"<br>",N$1," ",N2,"<br>",O$1," ",O2,"<br>",P$1," ",P2,"<br>",Q$1," ",Q2,"<br><hr><br>")
Here's how it looks from my data:

quote:

Scott
Fruit: Apple
Vegetable: Cucumber
Meat:
Dessert: Ice cream
Drink: Beer
Starter:

--------------------------------------------------------------------------------

Alan
Fruit:
Vegetable: Lettuce
Meat: Pork
Dessert:
Drink: Wine
Starter:

--------------------------------------------------------------------------------

Don
Fruit: Banana
Vegetable:
Meat: Beef
Dessert:
Drink: Hard Liquor
Starter:

--------------------------------------------------------------------------------


But I want unanswered questions hidden for each person. I WANT it to look like this:

quote:

Scott
Fruit: Apple
Vegetable: Cucumber
Dessert: Ice cream
Drink: Beer

--------------------------------------------------------------------------------

Alan
Vegetable: Lettuce
Meat: Pork
Drink: Wine

--------------------------------------------------------------------------------

Don
Fruit: Banana
Meat: Beef
Drink: Hard Liquor

--------------------------------------------------------------------------------


Can anyone help? Sorry to be so dense...

EDIT: Happy to offer $20 via PayPal to whomever can help...

RICHUNCLEPENNYBAGS
Dec 21, 2010
Why can't you do something like: CONCATENATE(A1, IF(ISBLANK(A2), "", "Foo: " & A2))

I might consider using line breaks to make this less confusing... also perhaps & instead of the concatenate function.

This is good stuff.

RICHUNCLEPENNYBAGS fucked around with this message at 02:28 on Aug 3, 2013

Zorak of Michigan
Jun 10, 2006

Requiem posted:

Hi again, folks. I'm stumped again trying to combine ISBLANK and CONCATENATE. I find I'm smart enough to regurgitate your help (from June, p. 25 of this thread) but not to troubleshoot when I'm altering the context. Sorry...

Here's the formula I currently have:
code:
=CONCATENATE(A2,"<br>",L$1," ",L2,"<br>",M$1," ",M2,"<br>",N$1," ",N2,"<br>",O$1," ",O2,"<br>",P$1," ",P2,"<br>",Q$1," ",Q2,"<br><hr><br>")
Here's how it looks from my data:


But I want unanswered questions hidden for each person. I WANT it to look like this:


Can anyone help? Sorry to be so dense...

EDIT: Happy to offer $20 via PayPal to whomever can help...

E:fb.

This is notably filthy and there may be a cleaner way to do it, but the brute force approach looks like this:

code:
=A2&"<br>"&IF(ISBLANK(L2),,(L$1&": "&L2&"<br>"))&IF(ISBLANK(M2),,(M$1&": "&M2&"<br>"))
&IF(ISBLANK(N2),,(N$1&": "&N2&"<br>"))&IF(ISBLANK(O2),,(O$1&": "&O2&"<br>"))
&IF(ISBLANK(P2),,(P$1&": "&P2&"<br>"))&IF(ISBLANK(Q2),,(Q$1&": "&Q2&"<br>"))&"<hr><br>"
It's frustrating that it repeats the basic cell, space, colon, space, cell structure over and over again, but it looks like you'd need to dip into VBA to construct something more sophisticated. In any case this looks to do what you want.

You were clearly on a workable track with ISBLANK. You just need to get the if functions in order.

Zorak of Michigan fucked around with this message at 02:48 on Aug 3, 2013

RICHUNCLEPENNYBAGS
Dec 21, 2010
That VBA would probably look something like this:

code:
Function AttribSkipBlank(MyAttribute As String, MyValue As String) As String
  Dim MyText As String


  If MyValue <> "" Then
    MyText = MyAttribute & ":  " & MyValue & "<br>"
  Else
    MyText = ""
  End If

AttribSkipBlank = MyText

End Function
	
Wrapping each field like that is a bit annoying, I guess, but it's less error-prone than the inline IFs for sure.

RICHUNCLEPENNYBAGS fucked around with this message at 03:47 on Aug 3, 2013

Requiem
Jan 29, 2003
You can't bring that weak-ass shit up in this humpity-bumpity! This ain't Club Med, baby!

Zorak of Michigan posted:

E:fb.

This is notably filthy and there may be a cleaner way to do it, but the brute force approach looks like this:

code:
=A2&"<br>"&IF(ISBLANK(L2),,(L$1&": "&L2&"<br>"))&IF(ISBLANK(M2),,(M$1&": "&M2&"<br>"))
&IF(ISBLANK(N2),,(N$1&": "&N2&"<br>"))&IF(ISBLANK(O2),,(O$1&": "&O2&"<br>"))
&IF(ISBLANK(P2),,(P$1&": "&P2&"<br>"))&IF(ISBLANK(Q2),,(Q$1&": "&Q2&"<br>"))&"<hr><br>"
It's frustrating that it repeats the basic cell, space, colon, space, cell structure over and over again, but it looks like you'd need to dip into VBA to construct something more sophisticated. In any case this looks to do what you want.

You were clearly on a workable track with ISBLANK. You just need to get the if functions in order.

Zorak, thanks very much. Your code worked perfectly--and all I had to do was cut and paste, which for a guy who can see but not understand is a perfect solution!

PM me your PayPal info please?

With many thanks.

Zorak of Michigan
Jun 10, 2006

Thanks but there's no need to pay me for that load of mess. I'm just addicted to problem solving. Also RICHUNCLEPENNYBAGS got the explanation out first.

Unless you just don't give a crap, there's no reason to come away not understanding how this works. IF() has three sections- the logical test, the value for the cell if the test evaluates true, and the value if the test evaluates false. You already figured out that the right test for this is ISBLANK(), so you have to start with

code:
=IF(ISBLANK(L2),,)
If L2 is blank, we want to print nothing, so the value if true is nothing. No change required!

code:
=IF(ISBLANK(L2),,)
If L2 is something, then ISBLANK(L2) is false. In that case we want the cell to print the value of L$1, then a colon and a space, then the value of L2, then the HTML linebreak. If we use the & operator to shove all that together, it becomes

code:
L$1&": "&L2&"<br>"
so we stick that in the last bit of our IF function, wrapping it in parentheses because it makes me feel better to do so, and it becomes

code:
=IF(ISBLANK(L2),,(L$1&": "&L2&"<br>"))
When you put it all together it starts to look a little like alphabet soup, but when you break it down, it's simple coding. Since you want to combine it all into one cell, the other IF functions all get concatenated with the first, which I did with the & operator just to keep the function a little shorter.

Requiem
Jan 29, 2003
You can't bring that weak-ass shit up in this humpity-bumpity! This ain't Club Med, baby!

Zorak of Michigan posted:

Thanks but there's no need to pay me for that load of mess. I'm just addicted to problem solving. Also RICHUNCLEPENNYBAGS got the explanation out first.

Unless you just don't give a crap, there's no reason to come away not understanding how this works. IF() has three sections- the logical test, the value for the cell if the test evaluates true, and the value if the test evaluates false. You already figured out that the right test for this is ISBLANK(), so you have to start with

You should make a living doing this. Thanks for the straightforward explanations. I admit I was stumped at & replacing CONCATENATE--it seemed like darkest of magic to me.

Thank you!

celestial teapot
Sep 9, 2003

He asked my religion and I replied "agnostic." He asked how to spell it, and remarked with a sigh: "Well, there are many religions, but I suppose they all worship the same God."
Edit: Reworked, see below

celestial teapot fucked around with this message at 19:22 on Aug 7, 2013

celestial teapot
Sep 9, 2003

He asked my religion and I replied "agnostic." He asked how to spell it, and remarked with a sigh: "Well, there are many religions, but I suppose they all worship the same God."
I lifted this RegEx replace module off some blog post, haven't tested it but it looks solid

code:
 '---------------------------------------------------------------------------------------
 ' Copyright : ?
 ' Purpose   : Regular expression library
 ' License   : ?
 ' Retrieved : [url]https://excelicious.wordpress.com/code-samples/vba/regex-functions/[/url]
 '---------------------------------------------------------------------------------------

Public Function RXFIND(ByRef find_pattern As String, _
                        ByRef within_text As String, _
                        Optional ByVal start_num As Long = 0, _
                        Optional ByVal case_sensitive As Boolean = True) As Variant
' RXFIND - Returns the starting position of text matching the regex pattern
' find_pattern in the string within_text, if a match is found.
' Optional long start_num specifies the number of the character in within_text
' to start matching. Default=0.
' Optional boolean case_sensitive makes the pattern case sensitive if true,
' insensitive otherwise. Default=true.

    Dim objRegex As VBScript_RegExp_55.RegExp
    Dim colMatch As VBScript_RegExp_55.MatchCollection
    Dim vbsMatch As VBScript_RegExp_55.Match
    Dim sMatchString As String
    
    Set objRegex = New VBScript_RegExp_55.RegExp
    
    ' Initialise Regex object
    With objRegex
        .Global = False
        ' Default is case sensitive
        If case_sensitive Then
            .IgnoreCase = False
        Else: .IgnoreCase = True
        End If
        .Pattern = find_pattern
    End With
    
    ' Return out of bounds error
    If start_num >= Len(within_text) Then
        RXFIND = CVErr(xlErrNum)
        Exit Function
    End If
    
    ' Get string from char at start_num
    sMatchString = Right$(within_text, Len(within_text) - start_num)
    
    ' Create Match collection
    Set colMatch = objRegex.Execute(sMatchString)
    If colMatch.count = 0 Then ' No match
        RXFIND = 0
    Else
        Set vbsMatch = colMatch(0)
        RXFIND = vbsMatch.FirstIndex + start_num + 1
    End If
End Function

Public Function ISRXMATCH(ByRef find_pattern As Variant, _
                        ByRef within_text As Variant, _
                        Optional ByVal case_sensitive As Boolean = True) As Boolean
' ISRXMATCH - Returns true if the regex pattern find_pattern is matched
' in the string within_text, false otherwise.
' Optional boolean case_sensitive makes the pattern case sensitive if true,
' insensitive otherwise. Default=true.

    Dim objRegex As VBScript_RegExp_55.RegExp
    
    Set objRegex = New VBScript_RegExp_55.RegExp
    
    ' Initialise Regex object
    With objRegex
        .Global = False
        ' Default is case sensitive
        If case_sensitive Then
            .IgnoreCase = False
        Else: .IgnoreCase = True
        End If
        .Pattern = find_pattern
    End With
    
    ' Test for pattern and return result
    ISRXMATCH = objRegex.Test(within_text)

End Function

Public Function RXGET(ByRef find_pattern As Variant, _
                        ByRef within_text As Variant, _
                        Optional ByVal submatch As Long = 0, _
                        Optional ByVal start_num As Long = 0, _
                        Optional ByVal case_sensitive As Boolean = True) As Variant
' RXGET - Looks for a match for regular expression pattern find_pattern
' in the string within_text and returns it if found, error otherwise.
' Optional long submatch may be used to return the corresponding submatch
' if specified - otherwise the entire match is returned.
' Optional long start_num specifies the number of the character to start
' searching for in within_text. Default=0.
' Optional boolean case_sensitive makes the regex pattern case sensitive
' if true, insensitive otherwise. Default=true.

    Dim objRegex As VBScript_RegExp_55.RegExp
    Dim colMatch As VBScript_RegExp_55.MatchCollection
    Dim vbsMatch As VBScript_RegExp_55.Match
    Dim colSubMatch As VBScript_RegExp_55.SubMatches
    Dim sMatchString As String
    
    Set objRegex = New VBScript_RegExp_55.RegExp
    
    ' Initialise Regex object
    With objRegex
        .Global = False
        ' Default is case sensitive
        If case_sensitive Then
            .IgnoreCase = False
        Else: .IgnoreCase = True
        End If
        .Pattern = find_pattern
    End With
    
    ' Return out of bounds error
    If start_num >= Len(within_text) Then
        RXGET = CVErr(xlErrNum)
        Exit Function
    End If
    sMatchString = Right$(within_text, Len(within_text) - start_num)
    
    ' Create Match collection
    Set colMatch = objRegex.Execute(sMatchString)
    If colMatch.count = 0 Then ' No match
        RXGET = CVErr(xlErrNA)
    Else
        Set vbsMatch = colMatch(0)
        If submatch = 0 Then ' Return match value
            RXGET = vbsMatch.Value
        Else
            Set colSubMatch = vbsMatch.SubMatches ' Use the submatch collection
            If colSubMatch.count < submatch Then
                RXGET = CVErr(xlErrNum)
            Else
                RXGET = CStr(colSubMatch(submatch - 1))
            End If
        End If
    End If
End Function

celestial teapot
Sep 9, 2003

He asked my religion and I replied "agnostic." He asked how to spell it, and remarked with a sigh: "Well, there are many religions, but I suppose they all worship the same God."
Did this one the other day, don't think I posted it yet
code:
Public Function Coalesce(ParamArray haystack() As Variant) As Variant
 '---------------------------------------------------------------------------------------
 ' Copyright : 2013-08-01
 ' Author    : celestial teapot
 ' Purpose   : Returns the first of the haystack that has length greater than zero
 ' License   : MIT License [url]http://opensource.org/licenses/MIT[/url]
 '---------------------------------------------------------------------------------------
    
    Dim proc_name As String
    proc_name = "Coalesce"
    On Error GoTo ErrorHandler
    
    '''''''''''''''''''
    'Variables        '
    '''''''''''''''''''
    Dim i As Integer
    
    '''''''''''''''''''
    'Declarations     '
    '''''''''''''''''''
    i = 0                               'Start with the 0th array item
    
    '''''''''''''''''''
    'Action           '
    '''''''''''''''''''
    Do While Len(haystack(i)) = 0       'While the "i"th array item is length zero
        i = i + 1                       'Go to the next one
        If UBound(haystack) < i Then    'Unless we hit the end already
            Coalesce = xlErrValue       'Then return an error value
            GoTo Endgame                'and get the gently caress out of here
        End If
    Loop
    
    Coalesce = haystack(i)              'Return the first non-null value in the list of haystack
    
Endgame:
    Exit Function       'Exit before error handler
ErrorHandler:
    MsgBox "There was an unhandled exception in function " _
              & proc_name & _ 
              ". Source: " & Err.Source & _
              "Error number: " & Err.Number & _ 
              " Description: " & Err.Description
    Resume Endgame
End Function

celestial teapot fucked around with this message at 19:55 on Aug 6, 2013

celestial teapot
Sep 9, 2003

He asked my religion and I replied "agnostic." He asked how to spell it, and remarked with a sigh: "Well, there are many religions, but I suppose they all worship the same God."
I reworked the functions for counting distinct values by splitting them into separate functions using arrays.
code:
Public Function Distinct(ByRef haystack As Variant) As Variant
 '---------------------------------------------------------------------------------------
 ' Copyright : 2013-08-06
 ' Author    : celestial teapot
 ' Purpose   : Take an array and return an array with only the distinct values
 ' License   : MIT License [url]http://opensource.org/licenses/MIT[/url]
 '---------------------------------------------------------------------------------------
    
    Dim proc_name As String
    proc_name = "Distinct"
    On Error GoTo ErrorHandler
    
    '''''''''''''''''''
    'Variables        '
    '''''''''''''''''''
    Dim i As Long
    Dim lower As Long
    Dim upper As Long
    Dim dict As Scripting.Dictionary
    
    '''''''''''''''''''
    'Declarations     '
    '''''''''''''''''''
    Set dict = New Scripting.Dictionary
    
    '''''''''''''''''''
    'Action           '
    '''''''''''''''''''
    lower = LBound(haystack)                      'Start with the first non-null value in the array
    upper = UBound(haystack)                      'And end with the last one! :haw:
    
    For i = lower To upper                        'For each value in the array,
        dict.Add haystack(i, 1), i                'add it to a dictionary array (excludes duplication)
    Next i
    
    Distinct = dict.Items
    
Endgame:
    Exit Function            'Exit before error handler
ErrorHandler:
    
    If Err.Number = 457 Then                      'Ignore errors about duplicate dictionary values
        Resume Next
    End If
    
    MsgBox "There was an unhandled exception in function " _
              & proc_name & _
              ". Source: " & Err.Source & _
              "Error number: " & Err.Number & _
              " Description: " & Err.Description
    Resume Endgame
End Function
Since this returns an array with all the distinct values (including a zero length value, if there were any in the haystack) you can get a count of the distinct values by doing
code:
UBound(distinct(array))
So didn't turn that into a function.

Let me know if I should keep posting these.

celestial teapot fucked around with this message at 20:53 on Aug 7, 2013

esquilax
Jan 3, 2003

So my office recently upgraded from MS Office 2003 to Office 2010.

Most people there typically create tables in Excel and paste as a picture (enhanced metafile) into PowerPoint. When you do that using Office 2010 it copies the default gridlines and the red comment triangle and shows them when you paste the table. To make it look proper I need to remove gridlines and make sure the comments aren't being shown before I copy, which is annoying.

Is there any way copy and paste it as it show up if printed (i.e. no default gridlines, no comment or error triangles)?

celestial teapot
Sep 9, 2003

He asked my religion and I replied "agnostic." He asked how to spell it, and remarked with a sigh: "Well, there are many religions, but I suppose they all worship the same God."
To remove gridlines, fill the cell color as white and clear any borders that may have been applied to the cell styles.

To remove error flags, :google: holds the answer to this question.

I'm not familiar with power point but I am sure there is a better way to import your data into it.

esquilax
Jan 3, 2003

celestial teapot posted:

To remove gridlines, fill the cell color as white and clear any borders that may have been applied to the cell styles.

To remove error flags, :google: holds the answer to this question.

I'm not familiar with power point but I am sure there is a better way to import your data into it.

Well obviously. Those were the solutions that I posted to my own question. I just don't want to take an extra 15 seconds to hide grids and flags, copy and paste, and then spend another 15 seconds turning them back on.

I was asking if there is a better way to import.

Adbot
ADBOT LOVES YOU

celestial teapot
Sep 9, 2003

He asked my religion and I replied "agnostic." He asked how to spell it, and remarked with a sigh: "Well, there are many religions, but I suppose they all worship the same God."
If filling the cell with a background color is :effort: then any other excel-based solution (eg VBA) is going to be a lot more work than that.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply