Jump to content

Recommended Posts

Posted

Do you use Macros? If so what do you use?

 

I've developed one recently which is a godsend here (save file as a PDF, and automatically attach to an email). Just looking at what else could be useful for us and what others have developed.

 

Here is my code for the macro I developed :)

 

Sub Send_PDF()
   Dim oOutlookApp As Outlook.Application
   Dim oItem As Outlook.MailItem
   On Error Resume Next
   Dim MyFile As String
   MyFile = ActiveDocument.Name
   intPos = InStrRev(MyFile, ".")
   If intPos > 0 Then
       MyFile = Left(MyFile, intPos - 1)
   End If
   Dim FSO As Object, TmpFolder As Object
   Set FSO = CreateObject("scripting.filesystemobject")
   Set FileName = FSO.GetSpecialFolder(2)
   FileName = FileName & "\" & MyFile & ".pdf"
   ActiveDocument.ExportAsFixedFormat OutputFileName:= _
       FileName, ExportFormat:= _
       wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:= _
       wdExportOptimizeForPrint, Range:=wdExportAllDocument, From:=0, To:=0, _
       Item:=wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
       CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
       BitmapMissingFonts:=True, UseISO19005_1:=False
   Set oOutlookApp = GetObject(, "Outlook.Application")
   If Err <> 0 Then
       Set oOutlookApp = CreateObject("Outlook.Application")
   End If
   Set oItem = oOutlookApp.CreateItem(olMailItem)
   oItem.Attachments.Add FileName
   oItem.Display
   Set FSO = Nothing
   Set FileName = Nothing
   Set oOutlookApp = Nothing
   Set oItem = Nothing
   
End Sub

Posted
Do you use Macros? If so what do you use?

 

We use them mainly for formatting extracts from SIMS and Go4Schools - gets the data into the standard report in a few clicks.

 

I find that the built-in functions are now so varied and powerful that a lot of the things I was writing macros for in my early career are now pre-defined.

Posted
Do you use Macros? If so what do you use?

 

I've developed one recently which is a godsend here (save file as a PDF, and automatically attach to an email). Just looking at what else could be useful for us and what others have developed.

 

Here is my code for the macro I developed :)

 

Sub Send_PDF()
   Dim oOutlookApp As Outlook.Application
   Dim oItem As Outlook.MailItem
   On Error Resume Next
   Dim MyFile As String
   MyFile = ActiveDocument.Name
   intPos = InStrRev(MyFile, ".")
   If intPos > 0 Then
       MyFile = Left(MyFile, intPos - 1)
   End If
   Dim FSO As Object, TmpFolder As Object
   Set FSO = CreateObject("scripting.filesystemobject")
   Set FileName = FSO.GetSpecialFolder(2)
   FileName = FileName & "\" & MyFile & ".pdf"
   ActiveDocument.ExportAsFixedFormat OutputFileName:= _
       FileName, ExportFormat:= _
       wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:= _
       wdExportOptimizeForPrint, Range:=wdExportAllDocument, From:=0, To:=0, _
       Item:=wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
       CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
       BitmapMissingFonts:=True, UseISO19005_1:=False
   Set oOutlookApp = GetObject(, "Outlook.Application")
   If Err <> 0 Then
       Set oOutlookApp = CreateObject("Outlook.Application")
   End If
   Set oItem = oOutlookApp.CreateItem(olMailItem)
   oItem.Attachments.Add FileName
   oItem.Display
   Set FSO = Nothing
   Set FileName = Nothing
   Set oOutlookApp = Nothing
   Set oItem = Nothing
   
End Sub

 

How/Where do you learn to code to write your own Macros?

Posted
How/Where do you learn to code to write your own Macros?

 

Well many of the macros are built in as said before, but some we needed here were specific to the company. We have one that does the same as above, but exports everything to our letter template as well.

 

I learnt to write macros through the VB recorder program built into office, and looked at how it was structured, then learnt VBA on top. I write what I believe is useful, but I was just curious as to what else is there that I may have missed and could be used here.

  • Thanks 1
Posted (edited)

I have an Add-In full of macros for Excel that have been developed over the years. As @Seb1780 said though, Office has come on a long way so that I probably ought to purge them really.

 

Here are two that are very useful in conjunction and can be used the same way as any standard Excel formula in a spreadsheet. Pretty self explanartory what they do, I find them very helpful in summarising RAG coloured marksheets coming out of SIMS:

 

Public Function cell_colour(Cell_Check As Range) As Long
   cell_colour = Cell_Check.Interior.Color
End Function

Public Function count_colour(Count_Range As Range, Colour As Long) As Long
Dim x As Range
count_colour = 0
For Each x In Count_Range
   If x.Interior.Color = Colour Then
       count_colour = count_colour + 1
   End If
Next x
End Function

 

Then there's my "Special Lookup" - similar VLookup, but you can set the row and column offset to return from the found result (which can be anywhere in the specified range), and specify a custom value to return if no match is found. You can achieve the same with Index and Match but it gets complicated very quickly.

 

Public Function SPECIAL_LOOKUP(lookup_value As String, lookup_range As Range, Optional column_offset As Long = 0, Optional row_offset As Long = 0, Optional on_error As Variant = "NOT FOUND") As Variant
On Error Resume Next
Dim x As Variant
For Each x In lookup_range
   If x.Value = lookup_value Then
       SPECIAL_LOOKUP = x.Offset(row_offset, column_offset).Value
       Exit Function
   End If
Next x
SPECIAL_LOOKUP = on_error
End Function

 

Next in my list of useful Excel macros is "Clone Footer". I made this because, irritatingly, highlighting all sheets to try to change the footer for them all not only changes the footer, but all the page setup options. I discovered this the hard way when trying to change the footer on a 20+ sheet workbook with a mixture of landscape/portrait pages :doh:. This one needs to be called from the editor or, as I have done, a custom menu option. Open the sheet containing the footer you want cloning to the other sheets, run it and job done:

 

Public Sub CloneFooter()
If ActiveWorkbook.Windows(1).SelectedSheets.Count > 1 Then
   MsgBox "Please select only the sheet containing the footer you'd like to clone to all other sheets in the workbook", vbOKOnly + vbExclamation, "Error"
   Exit Sub
End If

lFooter = ActiveWorkbook.ActiveSheet.PageSetup.LeftFooter
cFooter = ActiveWorkbook.ActiveSheet.PageSetup.CenterFooter
rFooter = ActiveWorkbook.ActiveSheet.PageSetup.RightFooter

For Each s In ActiveWorkbook.Sheets
   s.PageSetup.LeftFooter = lFooter
   s.PageSetup.CenterFooter = cFooter
   s.PageSetup.RightFooter = rFooter
Next s
End Sub

 

Finally (for now!) here's one that will take a given post code and look it up on the Ordnance Survey database, returning the authority responsible. Created this as our SEN department needed a reliable way to identify which authorities to bill for their SEN students (incidentally, this one is attached to a SIMS report to do this all automatically, if anyone wants that report PM me). This is used like any other Excel formula:

 

Public Function OSGetDistrict(PostCode As String) As String
Dim rows() As String
Dim cols() As String
Dim oHttp As Object
Set oHttp = CreateObject("Microsoft.XMLHTTP")
myURL = "http://data.ordnancesurvey.co.uk/datasets/os-linked-data/apis/sparql?query=PREFIX+rdfs%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3E%0D%0APREFIX+postcode%3A+%3Chttp%3A%2F%2Fdata.ordnancesurvey.co.uk%2Fontology%2Fpostcode%2F%3E%0D%0A%0D%0ASELECT+DISTINCT+%3Fdistrict+%3Fname%0D%0AWHERE+%7B%0D%0A%0D%0A%3Fpostcode+rdfs%3Alabel+%22" + Replace(PostCode, " ", "+") + "%22+%3B%0D%0A+postcode%3Adistrict+%3Fdistrict+.%0D%0A%3Fdistrict+rdfs%3Alabel+%3Fname++.%0D%0A%7D&output=csv"
oHttp.Open "GET", myURL, False
oHttp.send
If oHttp.Status < 300 Then
   rows = Split(oHttp.responseText, vbNewLine)
   cols = Split(rows(1), ",")
   If UBound(cols) < 1 Then
       OSGetDistrict = "Postcode Not Recognised"
   Else
       OSGetDistrict = cols(1)
   End If
Else
   OSGetDistrict = "Server Error: " + oHttp.Status
End If
End Function

Edited by LosOjos
  • Thanks 2
Posted

Oh I also have macros for inserting watermarks on all pages (yes people are that lazy here! haha). But in Word 2010, it is a nuisance that the watermark only appears on the top page unless you go through the procedure of doing a custom one every time. Atleast with this, it cuts down the time (and phone calls). We also added in a few of our own as well, but these are the standard ones.

 

Also, only 1 watermark at a time works with this, but I've never known someone to need a combination of watermarks however.

 

Sub InsertDraftWaterMark()
   ActiveDocument.Sections(1).Range.Select
   ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
   Selection.HeaderFooter.Shapes.AddTextEffect( _
       PowerPlusWaterMarkObject, "DRAFT", "Calibri", 1, False, False, _
       0, 0).Select
   Selection.ShapeRange.Name = "PowerPlusWaterMarkObject"
   Selection.ShapeRange.TextEffect.NormalizedHeight = False
   Selection.ShapeRange.Line.Visible = False
   Selection.ShapeRange.Fill.Visible = True
   Selection.ShapeRange.Fill.Solid
   Selection.ShapeRange.Fill.ForeColor.RGB = RGB(192, 192, 192)
   Selection.ShapeRange.Fill.Transparency = 0.5
   Selection.ShapeRange.Rotation = 315
   Selection.ShapeRange.LockAspectRatio = True
   Selection.ShapeRange.Height = CentimetersToPoints(8.42)
   Selection.ShapeRange.Width = CentimetersToPoints(14.03)
   Selection.ShapeRange.WrapFormat.AllowOverlap = True
   Selection.ShapeRange.WrapFormat.Side = wdWrapNone
   Selection.ShapeRange.WrapFormat.Type = 3
   Selection.ShapeRange.RelativeHorizontalPosition = _
       wdRelativeVerticalPositionMargin
   Selection.ShapeRange.RelativeVerticalPosition = _
       wdRelativeVerticalPositionMargin
   Selection.ShapeRange.Left = wdShapeCenter
   Selection.ShapeRange.Top = wdShapeCenter
   ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
End Sub

Sub InsertCopyWaterMark()
   ActiveDocument.Sections(1).Range.Select
   ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
   Selection.HeaderFooter.Shapes.AddTextEffect( _
       PowerPlusWaterMarkObject, "COPY", "Calibri", 1, False, False, _
       0, 0).Select
   Selection.ShapeRange.Name = "PowerPlusWaterMarkObject"
   Selection.ShapeRange.TextEffect.NormalizedHeight = False
   Selection.ShapeRange.Line.Visible = False
   Selection.ShapeRange.Fill.Visible = True
   Selection.ShapeRange.Fill.Solid
   Selection.ShapeRange.Fill.ForeColor.RGB = RGB(192, 192, 192)
   Selection.ShapeRange.Fill.Transparency = 0.5
   Selection.ShapeRange.Rotation = 315
   Selection.ShapeRange.LockAspectRatio = True
   Selection.ShapeRange.Height = CentimetersToPoints(8.42)
   Selection.ShapeRange.Width = CentimetersToPoints(14.03)
   Selection.ShapeRange.WrapFormat.AllowOverlap = True
   Selection.ShapeRange.WrapFormat.Side = wdWrapNone
   Selection.ShapeRange.WrapFormat.Type = 3
   Selection.ShapeRange.RelativeHorizontalPosition = _
       wdRelativeVerticalPositionMargin
   Selection.ShapeRange.RelativeVerticalPosition = _
       wdRelativeVerticalPositionMargin
   Selection.ShapeRange.Left = wdShapeCenter
   Selection.ShapeRange.Top = wdShapeCenter
   ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
End Sub

Sub InsertConfidentialWaterMark()
   ActiveDocument.Sections(1).Range.Select
   ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
   Selection.HeaderFooter.Shapes.AddTextEffect( _
       PowerPlusWaterMarkObject, "CONFIDENTIAL", "Calibri", 1, False, False, _
       0, 0).Select
   Selection.ShapeRange.Name = "PowerPlusWaterMarkObject"
   Selection.ShapeRange.TextEffect.NormalizedHeight = False
   Selection.ShapeRange.Line.Visible = False
   Selection.ShapeRange.Fill.Visible = True
   Selection.ShapeRange.Fill.Solid
   Selection.ShapeRange.Fill.ForeColor.RGB = RGB(192, 192, 192)
   Selection.ShapeRange.Fill.Transparency = 0.5
   Selection.ShapeRange.Rotation = 315
   Selection.ShapeRange.LockAspectRatio = True
   Selection.ShapeRange.Height = CentimetersToPoints(8.42)
   Selection.ShapeRange.Width = CentimetersToPoints(14.03)
   Selection.ShapeRange.WrapFormat.AllowOverlap = True
   Selection.ShapeRange.WrapFormat.Side = wdWrapNone
   Selection.ShapeRange.WrapFormat.Type = 3
   Selection.ShapeRange.RelativeHorizontalPosition = _
       wdRelativeVerticalPositionMargin
   Selection.ShapeRange.RelativeVerticalPosition = _
       wdRelativeVerticalPositionMargin
   Selection.ShapeRange.Left = wdShapeCenter
   Selection.ShapeRange.Top = wdShapeCenter
   ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
End Sub

Sub RemoveWaterMark()
   Dim oSection As Section
Dim oHeader As HeaderFooter
Dim oRng As Range
Dim oShape As Shape
   For Each oSection In ActiveDocument.Sections
       For Each oHeader In oSection.Headers
           If oHeader.Exists Then
               Set oRng = oHeader.Range
               oRng.End = oRng.Paragraphs(1).Range.End - 1
               For Each oShape In oRng.ShapeRange
                   If oShape.Type = 15 Then oShape.Delete
               Next oShape
           End If
       Next oHeader
   Next oSection
End Sub

Posted
The postcode lookup one is handy for here, @LosOjos however, I can't seem to get it to work. Any help?

 

What exactly is the problem? Are you getting any errors? No results? Where are you using it?

 

Come on @nephilim give us a decent error report man! :p

Posted (edited)
haha. It is telling me it isn't a macro, so I made it a sub, and added an end sub, then it fails on opening. Just can't get it to work!

 

Can you export it and post it up on here?

 

It's a function, running it as a Sub won't return anything. You need to create a module in your workbook's VBA project, then paste the code in to that module. Then you use it just as you would any other Excel function, i.e. type in a cell (assuming cell A1 contains a post code):

=OSGetDistrict(A1)

 

I've attached an example for you (in Excel 97 format because that works for everyone!) :)

 

EDIT: I should point out that you'll have to bear in mind this macro looks up each postcode individually from the OS DB, so be prepared to wait for it if you are looking up a lot of them! Also worth mentioning if you plan to use this in a report you wish to save, copy/paste as values the postcodes when they've been looked up, otherwise every time Excel tries to recalculate formulas (every time you edit a cell by default), it'll redo each lookup, which can get very annoying!

 

PS: Randomly generating data may be one of my favourite time wasters... time to get out more!

OSGetDistrict_Example.xls

Edited by LosOjos
Posted

OK, I need help here

 

I have created a Macro, which *should* allow someone to click a button, and it opens and prints all attachments (some people here get emails with around 200+ attachments and it is a hassle to open each one manually then print).

 

Sub AttachmentPrint(Item As Outlook.MailItem)
   On Error GoTo OError
     
   'detect Temp
   Dim oFS As FileSystemObject
   Dim sTempFolder As String
   Set oFS = New FileSystemObject
   'Temporary Folder Path
   sTempFolder = oFS.GetSpecialFolder(TemporaryFolder)
   
   'creates a special temp folder
   cTmpFld = sTempFolder & "\OETMP" & Format(Now, "yyyymmddhhmmss")
   MkDir (cTmpFld)
   
   'save & print
   Dim oAtt As Attachment
   For Each oAtt In Item.Attachments
     FileName = oAtt.FileName
     FullFile = cTmpFld & "\" & FileName
     
     'save attachment
     oAtt.SaveAsFile (FullFile)
     
     'prints attachment
     Set objShell = CreateObject("Shell.Application")
     Set objFolder = objShell.NameSpace(0)
     Set objFolderItem = objFolder.ParseName(FullFile)
     objFolderItem.InvokeVerbEx ("print")

   Next oAtt
   
   'Cleanup
   If Not oFS Is Nothing Then Set oFS = Nothing
   If Not objFolder Is Nothing Then Set objFolder = Nothing
   If Not objFolderItem Is Nothing Then Set objFolderItem = Nothing
   If Not objShell Is Nothing Then Set objShell = Nothing
   
OError:
   If Err <> 0 Then
     MsgBox Err.Number & " - " & Err.Description
     Err.Clear
   End If
   Exit Sub

 End Sub

 

Trouble is, outlook 2010 doesn't see it as a macro.

Posted (edited)
OK, I need help here

 

I have created a Macro, which *should* allow someone to click a button, and it opens and prints all attachments (some people here get emails with around 200+ attachments and it is a hassle to open each one manually then print).

 

Trouble is, outlook 2010 doesn't see it as a macro.

 

How are you trying to call the macro? Strictly speaking, a sub routine which takes arguments isn't a macro as it's not automatic - a true macro is simply a script that calls other VBA functions automatically, not requiring initialization of it's own*. If you're trying to run the macro from the "Macros" menu, then I suspect this is why you're not seeing it.

 

You need to decide on how you are going to pass the MailItem object to your sub routine. If it's a case of you want the user to highlight a message in the viewing pane, click on the macro button and have it do it's thing, you could either rewrite the script to pick up the MailItem automatically, or write a "wrapper" macro that calls the sub routine passing it the MailItem it needs.

 

To take my example of automatically getting the currently selected item in the view pane, you could use this macro:

 

Sub ExtractAttachments()
Dim i As Integer
With Me.Application.ActiveExplorer.Selection
   If .Count > 0 Then
       For i = 1 To .Count
           If TypeOf .Item(i) Is Outlook.MailItem Then AttachmentPrint .Item(i)
       Next i
   End If
End With
End Sub

 

Now, whether you want to do that in the sub routine itself or as a new macro is up to you, but the advantage of using a wrapper is that you can then create macros to be called from any kind of view that will do the job of finding the MailItem then pass it to your sub to do the leg work.

 

* that's my understanding anyway, there may be more to it than that but it's a general rule that's always rang true for me!

Edited by LosOjos
Garbage debug code removed/corrected :)
Posted
ok, @LosOjos, got a good one for you...

 

replace section breaks with page breaks, then print said document, then put back the original section breaks.

 

I can get to the point where it prints, but wont replace the original section break.

 

Hmmm before I look at it, I'm curious as to why? Section breaks are often used for pages that require totally different formatting, such as a landscape page in the middle of a portrait document, or for creating indexes. Both those things would break if the sections were removed, making the print out wrong in the process...

 

I suppose what I'm really asking is, what is the end goal? There may be a better solution.

Posted

We have a separate software now which deals with the section breaks as it will insert PDFs or Excel spreadsheets etc into where it should go (based on pages). As such not needed anymore.

 

However some people add them by habit so it doesn't work with our printing macro and we have to continually help with this. So having a macro or subroutine which will do this in 1 click will save us a lot of time in a working day...both end users and us

Posted

@nephilim - I still don't understand how this macro would be helpful in any way, sections and page breaks are totally different things... it'd be like writing a macro to replace all the tables in the document with pictures of kittens - not what the author intended (although that sounds like an hilarious prank...)

 

However, I still tried! Failed, but tried lol. The code below is my attempt; I can store copies of the sections, replace them with page breaks, but then trying to iterate back trhough the document replacing the new page breaks with the original sections is where I fall down... maybe you can work that bit out from here?

 

[color="#0000FF"]Sub[/color] SectionsToPageBreaks()
[color="#0000FF"]Dim [/color]i [color="#0000FF"]As Integer[/color]
[color="#0000FF"]Dim [/color]savedSections() [color="#0000FF"]As Section[/color]
[color="#0000FF"]ReDim[/color] savedSections(0 [color="#0000FF"]To[/color] 0)

[color="#0000FF"]With [/color]ActiveDocument.Range
   [color="#0000FF"]For[/color] i = 1 [color="#0000FF"]To[/color] .Sections.Count
       [color="#0000FF"]If[/color] .Sections(i).PageSetup.SectionStart <> wdSectionNewColumn [color="#0000FF"]Then[/color]
           [color="#0000FF"]ReDim Preserve[/color] savedSections(0 To [color="#0000FF"]UBound[/color](savedSections) + 1)
           [color="#0000FF"]Set[/color] savedSections([color="#0000FF"]UBound[/color](savedSections)) = .Sections(i)
       [color="#0000FF"]End If[/color]
   [color="#0000FF"]Next [/color]i
[color="#0000FF"]End With[/color]

[color="#0000FF"]With [/color]ActiveDocument.ActiveWindow.Selection
   [color="#008000"]' replace section breaks[/color]
   .StartOf wdStory, wdMove
   .Find.Text = "^b"
   .Find.Replacement.Text = "^m"
   .Find.Forward = [color="#0000FF"]True[/color]
   .Find.Execute Replace:=wdReplaceAll
   
  [color="#008000"] ' perform any actions you wish to with the newly formatted document here[/color]
   [color="#0000FF"]MsgBox [/color]"Replaced " & Str$([color="#0000FF"]UBound[/color](savedSections)) & " sections."
   
  [color="#008000"] ' iterate savedSections array, returning section breaks to original positions[/color]
   [color="#0000FF"]If UBound[/color](savedSections) > 1 [color="#0000FF"]Then[/color]
       .StartOf wdstroy, wdMove
       .Find.Replacement.Text = ""
       [color="#008000"]' skip first section, which is the start of the document[/color]
       [color="#0000FF"]For [/color]i = 2 [color="#0000FF"]To UBound[/color](savedSections)
           .Start = savedSections(i).Range.Start
           .Collapse wdCollapseStart
           .Find.Execute
           [color="#0000FF"]Select Case[/color] savedSections(i).PageSetup.SectionStart
               [color="#0000FF"]Case [/color]wdSectionContinuous
                   .InsertBreak wdSectionBreakContinuous
               [color="#0000FF"]Case [/color]wdSectionEvenPage
                   .InsertBreak wdSectionBreakEvenPage
               [color="#0000FF"]Case [/color]wdSectionNewPage
                   .InsertBreak wdSectionBreakNextPage
               [color="#0000FF"]Case [/color]wdSectionOddPage
                   .InsertBreak wdSectionBreakOddPage
           [color="#0000FF"]End Select[/color]
       [color="#0000FF"]Next [/color]i
   [color="#0000FF"]End If
End With
End Sub[/color]

Posted (edited)

I use a fair few pretty basic Macros. I sort of cheat as most of my Macros simply create and run Batch files!

 

I've posted this before but I shall post again, here's my main use:

 

Untitled.jpg

 

The 'PowerPing' macro is my fav. Use the drop down box to select the SIMS machine on the network, hit PowerPing and it updates the status bar detailing if it's online or not, whether SIMS is currently in use, the version of SIMS and whether the SOLUS3 agent is installed. Being at the LA and having about 1500 SIMS machines on the network, it's very handy!

 

From there you can then delete SIMS.net, uninstall the S3 agent, set the standard Connect.ini etc etc. It all helps to save a bit of time.

Untitled.jpg

Edited by MrMat
Posted

@MrMat can you post up that set of macros for me please? That would be handy (though I would edit it for other programs we use here).

@LosOjos I ended up getting it to copy selection to another page, replace the section breaks with page breaks then print that, then close and leave the original unaltered...best solution around for it, but I do appreciate your help. We use a bespoke software here which will insert items into a section break then print, but if they needed to print something using our formatted macros, the section break wouldn't work within the macros. Hence this needing to be done. But thank you anyway.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...