Hi i inherited a load of old classic ASP code that makes some updates to some tables in what i think was old MS access db.
The databases have now been converted to SQL and work OK, however i have a need to convert some old ASP code to the equivalent TSQL. TSQL is NOT my strong point and would appreciate some help converting the vb script to the equivalent TSQL for a stored procedure called 'UpdateCircuitOrdersComments' its not the basic syntax i'm struggling with, its more what can be done IE FOR's IF's Cases, loops etc in order to achieve the below in sql.
I know the code below is not great or could be done far better, but that's what i inherited sorry.
Every field is available to me via c# parameters passed to the sproc using ajax apart from the "Contract Period"
Looking forward to learning from any sound advice from you guys...
The script is below:
Dim connect2, Class2, Query2, Counter
Dim indate1, indate2, indate3, aday1, amonth1, ayear1, aday2, amonth2, ayear2, aday3, amonth3, ayear3, length, maintrate, equiprate, stqrrate, startserial, liveserial, endserial
Dim splitArray
Set Connect = Server.CreateObject("ADODB.Connection")
Connect.Open QuotebaseDB
Set Class1 = Server.CreateObject("ADODB.Recordset")
Query = "SELECT * FROM circuits WHERE ID=" & Request("ID")
Class1.Open Query,Connect,adOpenDynamic,adLockOptimistic
if Class1("Contract Period") <> "" Then
length = Class1("Contract Period")
splitArray = split(length, " ")
length = CInt(splitArray(0))
else
length = 1
end if
Class1("actual live date") = Request("actuallivedate")
Class1("lastupdater") = Session("username")
Class1("lastupdate") = Date()
Class1("Contract Period") = length
Class1.Update
'=========================================
' Add Rate Information - Based On Actuals
'=========================================
indate1 = Request("actuallivedate")
indate2 = Request("actuallivedate")
indate3 = Request("actuallivedate")
aday1 = Left(indate1, 2)
amonth1 = Mid(indate1, 4, 2)
ayear1 = Right(indate1, 2)
aday2 = Left(indate2, 2)
amonth2 = Mid(indate2, 4, 2)
ayear2 = Right(indate2, 2)
aday3 = Left(indate3, 2)
amonth3 = Mid(indate3, 4, 2)
ayear3 = Right(indate3, 2) + length
startserial = dateserial(ayear1, amonth1, aday1)
liveserial = dateserial(ayear2, amonth2, aday2)
endserial = dateserial(ayear3, amonth3, aday3)
'========================================================
' Check that current maintenance rate will be superseded
'========================================================
Dim MaintConnect1, MaintRS1, MaintQuery1
Set MaintConnect1 = Server.CreateObject("ADODB.Connection")
MaintConnect1.Open QuotebaseDB
Set MaintRS1 = Server.CreateObject("ADODB.Recordset")
MaintQuery1 = "SELECT * FROM maintenancetable WHERE CircuitID=" & Request("ID")
MaintRS1.Open MaintQuery1,MaintConnect1,adOpenDynamic,adLockOptimistic
Do while not MaintRS1.eof
If (MaintRS1("startdate") < startserial) OR (MaintRS1("enddate") > endserial) Then
MaintRS1("startdate") = StartSerial
MaintRS1("enddate") = EndSerial
MaintRS1("circuitnum") = Class1("circuit number")
MaintRS1("modifieddate") = now
MaintRS1.Update
End If
MaintRS1.movenext
Loop
MaintRS1.close
set MaintRS1 = nothing
MaintConnect1.close
set MaintConnect1 = nothing
'========================================================
' Check that current equipment rate will be superseded
'========================================================
Dim EquipConnect1, EquipRS1, EquipQuery1
Set EquipConnect1 = Server.CreateObject("ADODB.Connection")
EquipConnect1.Open QuotebaseDB
Set EquipRS1 = Server.CreateObject("ADODB.Recordset")
EquipQuery1 = "SELECT * FROM [equipment table] WHERE CircuitID=" & Request("ID")
EquipRS1.Open EquipQuery1,EquipConnect1,adOpenDynamic,adLockOptimistic
Do while not EquipRS1.eof
If (EquipRS1("startdate") < startserial) OR (EquipRS1("enddate") > endserial) Then
EquipRS1("startdate") = StartSerial
EquipRS1("enddate") = EndSerial
EquipRS1("circuitnum") = Class1("circuit number")
EquipRS1("modifieddate") = now
EquipRS1.Update
End If
EquipRS1.movenext
Loop
EquipRS1.close
set EquipRS1 = nothing
EquipConnect1.close
set EquipConnect1 = nothing
'========================================================
' Check that current rental rate will be superseded
'========================================================
Dim STQRConnect1, STQRRS1, STQRQuery1
Set STQRConnect1 = Server.CreateObject("ADODB.Connection")
STQRConnect1.Open QuotebaseDB
Set STQRRS1 = Server.CreateObject("ADODB.Recordset")
STQRQuery1 = "SELECT * FROM STQRtable WHERE CircuitID=" & Request("ID")
STQRRS1.Open STQRQuery1,STQRConnect1,adOpenDynamic,adLockOptimistic
Do while not STQRRS1.eof
If (STQRRS1("startdate") < startserial) OR (STQRRS1("enddate") > endserial) Then
STQRRS1("startdate") = StartSerial
STQRRS1("enddate") = EndSerial
STQRRS1("circuitnum") = Class1("circuit number")
STQRRS1("modifieddate") = now
STQRRS1.Update
End If
STQRRS1.movenext
Loop
STQRRS1.close
set STQRRS1 = nothing
STQRConnect1.close
set STQRConnect1 = nothing
'===========================================
' Update Connection Charge As A One Off Charge
'===========================================
Dim OneConnect, OneRS, OneQuery
Set OneConnect = Server.CreateObject("ADODB.Connection")
OneConnect.Open QuotebaseDB
Set OneRS = Server.CreateObject("ADODB.Recordset")
OneQuery = "SELECT * FROM OneOffCharges WHERE chargetype = 'Connection Charge' and CircuitID=" & Request("ID")
OneRS.Open OneQuery,OneConnect,adOpenDynamic,adLockOptimistic
If not oners.eof Then
OneRS("chargedate") = startserial
OneRS("modifieddate") = now
OneRS("chargetype") = "Connection Charge"
OneRS.Update
End If
OneRS.close
set OneRS = nothing
OneConnect.close
set OneConnect = nothing
Class1.close
set Class1 = nothing
Connect.close
set Connect = nothing
The loops don't appear to do much other then iterate over the record set. It is unlikely that you will need to do this in T-SQL as you can probably deduce everything from queries.
Most of it just looks like update statements
-- Check that current maintenance rate will be superseded
UPDATE maintenancetable
SET StartDate = #startSerial,
EndDate = #endSerial,
CircuitNum = #circuitNumber,
ModifiedDate = CURRENT_TIMESTAMP
WHERE CircuitID=#circuitId
AND (Startdate < #startSerial OR EndDate > #endSerial)
The contract period is a bit confusing it seems to be getting the first item of an array so maybe this is the equivalent of
SELECT TOP 1 ContractPeriod FROM circuits WHERE ID=#id
-- ? ORDER BY ContractPeriod ?
Related
I am somewhat new to vba, and I'm trying to create a somewhat more complex conditional format than access 2013 allows from the conditional formatting menu. I have a form with 22 target date and actual date fields. for each pair I need to:
if the target date is more than 7 days in the future, color it green.
If the target date is less than 7 days in the future or is today, color it yellow
If the target date in the past, color it red.
UNLESS there is an actual date it was accomplished, in which case:
If the actual date is before the target date, color both dates green
If the actual date is after the target date, color both dates red.
Because I have to do this on form load, and on the change of any date field (the target dates are calculated, but will change if other data is changed in the form), I wanted to write a public sub that takes form name, target date, and actual date as variables. I was able to code each box to do this on the local form module with 'Me.txtbox'
However, when I try to reference the form and text boxes from the public sub, it seems like I'm not properly referencing the text boxes on the form. I've tried 3 or 4 different ways of doing this (string, textbox.name, etc) and I feel like I'm close, but ...
Code that works as desired in the form module
Private Sub txtFreqReqDate_AfterUpdate()
If Me.txtFreqReqDate <= Me.txtFreqReq Then
Me.txtFreqReq.Format = "mm/dd/yyyy[green]"
Me.txtFreqReqDate.Format = "mm/dd/yyyy[green]"
ElseIf Me.txtFreqReqDate > Me.txtFreqReq Then
Me.txtFreqReq.Format = "mm/dd/yyyy[red]"
Me.txtFreqReqDate.Format = "mm/dd/yyyy[red]"
ElseIf IsNull(Me.txtFreReqDate) = True Then
If Me.txtFreqReq < Now() Then
Me.txtFreqReq.Format = "mm/dd/yyyy[red]"
ElseIf Me.txtFreqReq >= (Now()+7) Then
Me.txtFreqReq.Format = "mm/dd/yyyy[yellow]"
ElseIf Me.txtFreqReq > (Now()+7) Then
Me.txtFreqReq.Format = "mm/dd/yyyy[green]"
Else
Me.txtFreqReq.Format = "mm/dd/yyyy[black]"
End If
Else
Exit Sub
End If
End Sub
Perhaps not the prettiest, but I'm always open to constructive criticism. I'd have to write this 22+ times for each pair, changing the name of the text boxes each time. I want to write a public sub that just takes the names of the text boxes, but I can't seem to find the right combination:
Private Sub txtFreqReqDate_AfterUpdate()
FormatBoxes(Me, me.txtFreqReqDate, me.txtFreqReq)
End Sub
And in another module:
Public Sub FormatBoxes(CurrentForm As Form, txtActual as Textbox, txtTarget as Textbox)
frmName = CurrentForm.name
tbActual = txtActual.Name
tbTarget = txtTarget.Name
If frmName.tbActual <= frmName.tbTarget Then
frmName.tbTarget.Format = "mm/dd/yyyy[green]"
frmName.tbActual.Format = "mm/dd/yyyy[green]"
ElseIf frmName.tbActual > frmName.tbTarget Then
frmName.tbTarget.Format = "mm/dd/yyyy[red]"
frmName.tbActual.Format = "mm/dd/yyyy[red]"
ElseIf IsNull(frmName.tbActual) = True Then
If frmName.tbTarget < Now() Then
frmName.tbTarget.Format = "mm/dd/yyyy[red]"
ElseIf frmName.tbTarget >= (Now()+7) Then
frmName.tbTarget.Format = "mm/dd/yyyy[yellow]"
ElseIf frmName.tbTarget > (Now()+7) Then
frmName.tbTarget.Format = "mm/dd/yyyy[green]"
Else
frmName.tbTarget.Format = "mm/dd/yyyy[black]"
End If
Else
Exit Sub
End If
End Sub
Sorry if this is a bit long, I'm just at my wit's end...
Also, apologies for any typos. I had to re-type this from another machine.
You can simply use the textbox parameters directly in your sub.
It is not even necessary to pass the form as parameter.
Public Sub FormatBoxes(txtActual as Textbox, txtTarget as Textbox)
If txtActual.Value <= txtTarget.Value Then
txtTarget.Format = "mm/dd/yyyy[green]"
etc.
Note that when calling it, you need either Call or remove the parentheses.
Private Sub txtFreqReqDate_AfterUpdate()
Call FormatBoxes(me.txtFreqReqDate, me.txtFreqReq)
' or
' FormatBoxes me.txtFreqReqDate, me.txtFreqReq
End Sub
CurrentForm.name is a string. It is the Name property of the CurrentForm object. The CurrentForm object also has a controls collection in which the texboxes live. You can refer to them by name in there like CurrentForm.Controls("tbTarget") but you can also say CurrentForm.tbTarget. So you're very close and on the right track.
Change
frmName = CurrentForm.name
tbActual = txtActual.Name
tbTarget = txtTarget.Name
to
set frmName = CurrentForm
if frmName is not nothing then
set tbActual = txtActual
set tbTarget = txtTarget
end if
Alternatively if your signature on your method is
Public Sub FormatBoxes(CurrentForm As string, txtActual as string, txtTarget as string)
then your set up will look like
set frmName = forms(CurrentForm)
if frmName is not nothing then
set tbActual = frmName.controls(txtActual)
set tbTarget = frmName.controls(txtTarget)
end if
But I think the first one will work better.
I wanted to post the finished code to help out anyone else who searches for this subject. I did a couple thins to make this sub more universal.
First, Instead of using the date format, I only changed the .ForeColor, allowing me to use this sub for any type of textbox.
Public Sub FormatBoxes(txtActual As TextBox, txtTarget As TextBox, chkRequired As CheckBox, _
Optional intOption as Integer)
Dim intRed As Long, intYellow As Long, intGreen As Long, inBlack As Long, intGray As Long
intBlack = RGB(0, 0, 0)
intGray = RGB(180, 180, 180)
intGreen = RGB (30, 120, 30)
intYellow = RGB(217, 167, 25)
intRed = RGB(255, 0, 0)
If (chkRequired = False) Then
txtTarget.ForeColor = intGray
txtActual.ForeColor = intGray
If intOption <> 1 Then
txtTarget.Enabled = False
txtActual.Enabled = False
txtTarget.TabStop = False
txtActual.TabStop = False
End If
Else
If intOption <> 1 Then
txtTarget.Enabled = True
txtActual.Enabled = True
txtTarget.Locked = True
txtActual.Locked = False
txtTarget.TabStop = False
txtActual.TabStop = True
End If
If IsBlank(txtActual) = True Then
If txtTarget < Now() Then
txtTarget.ForeColor = intRed
ElseIf txtTarget > (Now() + 7) Then
txtTarget.ForeColor = intGreen
ElseIf txtTarget >= Now() And txtTarget <= (Now() +7) Then
txtTarget.ForeColor = intYellow
Else
txtTarget.ForeColor = intBlack
End If
ElseIf intOption - 1 Then
txtTarget.ForeColor = intBlack
txtActual.ForeColor = intBlack
ElseIf txtActual <= txtTarget Then
txtTarget.ForeColor = intGreen
txtActual.ForeColor = intGreen
ElseIf txtActual > txtTarget Then
txtTarget.ForeColor = intRed
txtActual.ForeColor = intRed
End If
End If
End Sub
In case you were wondering, IsBlank() is a function that checks for a null or zero length string:
Public Function IsBlank(str_in As Variant) As Long
If Len(str_in & "") = 0 Then
IsBlank = -1
Else
IsBlank = 0
End If
End Function
Thanks for all the help, and I hope this is useful for someone.
I'm trying to set a company signature and then implement it with GPO.
Here's what I'm trying to accomplish:
John Hancock | Paralegal | Company, PC
<Logo (to the left of text)> 60 Test Street | PO Box 1389 | Testing, PA 19820
Phone: 555.555.5555| Fax: 555.555.5555 | Email: testing#testing.com (need this hyperlinked)
EDIT: Additional information from comments.
I'm trying to have different attributes (font size, font type, bold, etc) for the text in each particular line within the second row of the table. For example: Test text (this is bold and Calibri) - Test Text 2 (this is not bold and Arial). When I run the script as it stands, I get the logo on the left, in the first column, and a line of text to the right of the logo, in the second column. What I can't figure out is how to add another line of text, on the right, directly underneath the first line, and have that line of text show with different font attributes and such.
Here's the code I have so far:
Set objSysInfo = CreateObject("ADSystemInfo")
Set WshShell = CreateObject("WScript.Shell")
strUser = objSysInfo.UserName
Set objUser = GetObject("LDAP://" & strUser)
strName = objUser.FullName
strFirst = objUser.FirstName
strLast = objUser.LastName
strInitials = objUser.Initials
strOffice = objUser.physicalDeliveryOfficeName
strPOBox = objUser.postOfficeBox
strTitle = objUser.Description
strCred = objUser.info
strStreet = objUser.StreetAddress
strLocation = objUser.l
strPostCode = objUser.PostalCode
strPhone = objUser.TelephoneNumber
strMobile = objUser.Mobile
strFax = objUser.FacsimileTelephoneNumber
strEmail = objUser.mail
strCompany = objUser.Company
Const NUMBER_OF_ROWS = 1
Const NUMBER_OF_COLUMNS = 2
Set objWord = CreateObject("Word.Application")
Set objDoc = objWord.Documents.Add()
Set objSelection = objWord.Selection
Set objEmailOptions = objWord.EmailOptions
Set objSignatureObject = objEmailOptions.EmailSignature
Set objSignatureEntries = objSignatureObject.EmailSignatureEntries
Set objRange = objDoc.Range()
objDoc.Tables.Add objRange, NUMBER_OF_ROWS, NUMBER_OF_COLUMNS
Set objTable = objDoc.Tables(1)
Set objShape = objTable.Cell(1, 1).Range.Hyperlinks.Add(objSelection.InlineShapes.AddPicture("\\eg-fileserver\admin space\signature\logo.jpg"), "http://www.eastburngray.com",,,"")
objTable.Columns(1).Width = 20
objTable.Columns(2).Width = 320
objTable.Cell(1, 2).Range.Font.Bold = True
objTable.Cell(1, 2).Range.Font.Name = "Calibri"
objTable.Cell(1, 2).Range.Font.Size = 10
objTable.Range.ParagraphFormat.SpaceAfter = 0
objTable.Cell(1, 2).Range.Text = strFirst & strInitials & strLast & " | " & strOffice & " | " & strCompany
Set objSelection = objDoc.Range()
objSignatureEntries.Add "Full Signature", objSelection
objSignatureObject.NewMessageSignature = "Full Signature"
objDoc.Saved = True
objWord.Quit
The key to adding text with various formatting in Word is to work with a Range object. You can think of a Range like an invisible Selection, with the major difference that you can have as many Range objects as you need - there can be only one Selection. The trick to changing the formatting is to "collapse" the Range (think of it like pressing the Right- or Left-Arrow keys to a blinking "point", then continuing to type).
Edit Note: Based on bibadia's surmise that this is actually about VBScript and not VBA I've changed the tags in your question and am editing my Answer to fit VBScript. VBScript cannot use Word-specific object declarations and enumerations, so I've removed the "Dim As" and replaced all wdEnum with the Integer equivalent.
Using your code as a starting point, the approach could look something like this:
Dim rngCell
Set rngCell = objTable.Cell(1,2).Range
rngCell.ParagraphFormat.SpaceAfter = 0
rngCell.Text = strFirst & strInitials & strLast & " | " & _
strOffice & " | " & strCompany & vbCr
rngCell.Font.Bold = True
rngCell.Font.Name = "Calibri"
rngCell.Font.Size = 10
rngCell.Collapse 0 'wdCollapseEnd
rngCell.MoveEnd 1, -1 'wdCharacter, -1
rngCell.Text = strPhone & " | " & strFax & " | " & strEmail
rngCell.Font.Bold = False
rngCell.Font.Size = 8
Note 1: The order in which you do things is usually reversed from that when typing as a user: First populate the Range, then apply the formatting.
Note 2: When collapsing at the end of a cell, Word will move the Range position to the beginning of the following cell. Thus, the code moves the point back one character, putting it at the end of the previous (original) cell: rngCell.MoveEnd wdCharacter, -1
Note 3: I added a vbCr at the end of the first rngCell.Text to create the new paragraph within the table cell.
I am trying to update around 6000 rows in a table but my query never finishes.
I have put the data to be updated in a temp table and using a join to update rows.
This was working pretty fast in Sql Server but in Postgresql it never finishes.
I am updating around 40 columns.
Here is the sql I am running.
UPDATE "STG_magento_de".sales_flat_order
SET customer_id = b.customer_id
,created_at = b.created_at
,updated_at = b.updated_at
,coupon_code = b.coupon_code
,box_id = b.box_id
,beautytrends_glossydots = b.beautytrends_glossydots
,billing_address_id = b.billing_address_id
,shipping_address_id = b.shipping_address_id
,base_discount_amount = b.base_discount_amount
,base_discount_canceled = b.base_discount_canceled
,base_discount_invoiced = b.base_discount_invoiced
,base_discount_refunded = b.base_discount_refunded
,base_grand_total = b.base_grand_total
,base_shipping_amount = b.base_shipping_amount
,base_shipping_canceled = b.base_shipping_canceled
,base_shipping_invoiced = b.base_shipping_invoiced
,base_shipping_refunded = b.base_shipping_refunded
,base_shipping_tax_amount = b.base_shipping_tax_amount
,base_shipping_tax_refunded = b.base_shipping_tax_refunded
,base_subtotal = b.base_subtotal
,base_subtotal_canceled = b.base_subtotal_canceled
,base_subtotal_invoiced = b.base_subtotal_invoiced
,base_tax_amount = b.base_tax_amount
,base_tax_canceled = b.base_tax_canceled
,base_tax_invoiced = b.base_tax_invoiced
,base_tax_refunded = b.base_tax_refunded
,base_to_global_rate = b.base_to_global_rate
,base_to_order_rate = b.base_to_order_rate
,base_total_canceled = b.base_total_canceled
,base_total_invoiced = b.base_total_invoiced
,base_total_invoiced_cost = b.base_total_invoiced_cost
,base_total_offline_refunded = b.base_total_offline_refunded
,base_total_online_refunded = b.base_total_online_refunded
,base_total_paid = b.base_total_paid
,base_total_qty_ordered = b.base_total_qty_ordered
,base_total_refunded = b.base_total_refunded
,increment_id = b.increment_id
,order_type = b.order_type
,STATUS = b.STATUS
,is_chargerun = b.is_chargerun
,chargeback_flag = b.chargeback_flag
,gift_message_id = b.gift_message_id
,dispatch = b.dispatch
FROM "STG_magento_de".sales_flat_order a
JOIN "STG_magento_de".sales_flat_order_temp b ON a.entity_id = b.entity_id
From the manual:
Note that the target table must not appear in the from_list, unless you intend a self-join (in which case it must appear with an alias in the from_list).
(emphasis mine)
So you actually want:
UPDATE "STG_magento_de".sales_flat_order
SET customer_id = b.customer_id,
....
from sales_flat_order_temp b --<< do NOT repeat the target table here
where "STG_magento_de".sales_flat_order = b.entity_id`
Unrelated, but: you should really avoid those dreaded quoted identifiers. They are much more trouble than they are worth.
Basically what I am trying to do is, sending an email for every used row on the target worksheet, each row has the details of the addresses, subject line, table with values etc.
So I can't seem to get it working, as it only dispatches one email from the first target row (2nd row).
I have tried using a combination of For Each and For i = 1 to LR which aren't working. I suspect it is to do with the cell references.
Here is the code:
Sub TestEmail1()
Application.ScreenUpdating = False
Dim aOutlook As Object
Dim aEmail As Object
Dim rngeAddresses As Range, rngeCell As Range, strRecipients As String
Dim ccAddresses As Range, ccCell As Range, ccRecipients As String
Dim rngeSubject As Range, SubjectCell As Range, SubjectContent As Variant
Dim rngeBody As Range, bodyCell As Range, bodyContent As Variant
Dim Table1 As Range
Dim i As Integer
For Each c In ActiveSheet.UsedRange.Columns("A").Cells
Set rng = ActiveSheet.UsedRange
LRow = rng.Rows.Count
For i = 2 To LRow
Set Table1 = Worksheets(1).Range("K1:R1")
Set Table2 = Worksheets(2).Range("K" & i & ":" & "R" & i)
Set aOutlook = CreateObject("Outlook.Application")
Set aEmail = aOutlook.CreateItem(0)
'set sheet to find address for e-mails as I have several people to
'mail to
Set rngeAddresses = ActiveSheet.Range("B" & i)
For Each rngeCell In rngeAddresses.Cells
strRecipients = strRecipients & ";" & rngeCell.Value
Next
Set ccAddresses = ActiveSheet.Range("C" & i)
For Each ccCell In ccAddresses.Cells
ccRecipients = ccRecipients & ";" & ccCell.Value
Next
Set rngeSubject = ActiveSheet.Range("D" & i)
For Each SubjectCell In rngeSubject.Cells
SubjectContent = SubjectContent & SubjectCell.Value
Next
Set rngeBody = ActiveSheet.Range("E" & i)
For Each bodyCell In rngeBody.Cells
bodyContent = bodyContent & bodyCell.Value
Next
'set Importance
'aEmail.Importance = 2
'Set Subject
aEmail.Subject = rngeSubject
'Set Body for mail
'aEmail.Body = bodyContent
aEmail.HTMLBody = bodyContent & "<br><br><br>" & RangetoHTML_ (Table1)
aEmail.To = strRecipients
aEmail.CC = ccRecipients
aEmail.Send
Exit Sub
Next i
Next c
End Sub
There is an Exit Sub at the end of your inner loop that makes the code exit from the procedure after the first iteration:
Sub TestEmail1()
...
For Each c In ActiveSheet.UsedRange.Columns("A").Cells
...
For i = 2 To LRow
...
Exit Sub
Next i
Next c
End Sub
Remove it and processing should continue as desired.
Here is my macro. I assumed that I could understand the codes and then edit it and get what I wanted
First: The macro abends whitout any progress at all: "Compile error: userdefined typenot defined"
I dont even know what this meens :)
(I use the macro now in an new and emty workbook)
Sub ListAllItemsInInbox()
Dim OLF As Outlook.MAPIFolder, CurrUser As String
Dim EmailItemCount As Integer, i As Integer, EmailCount As Integer
Application.ScreenUpdating = False
Workbooks.Add ' create a new workbook
' add headings
Cells(1, 1).Formula = "Subject"
Cells(1, 2).Formula = "Recieved"
Cells(1, 3).Formula = "Attachments"
Cells(1, 4).Formula = "Read"
With Range("A1:D1").Font
.Bold = True
.Size = 14
End With
Application.Calculation = xlCalculationManual
Set OLF = GetObject("", _
"Outlook.Application").GetNamespace("MAPI").GetDefaultFolder(olFolderInbox)
EmailItemCount = OLF.Items.Count
i = 0: EmailCount = 0
' read e-mail information
While i < EmailItemCount
i = i + 1
If i Mod 50 = 0 Then Application.StatusBar = "Reading e-mail messages " & _
Format(i / EmailItemCount, "0%") & "..."
With OLF.Items(i)
EmailCount = EmailCount + 1
Cells(EmailCount + 1, 1).Formula = .Subject
Cells(EmailCount + 1, 2).Formula = Format(.ReceivedTime, "dd.mm.yyyy hh:mm")
Cells(EmailCount + 1, 3).Formula = .Attachments.Count
Cells(EmailCount + 1, 4).Formula = Not .UnRead
End With
Wend
Application.Calculation = xlCalculationAutomatic
Set OLF = Nothing
Columns("A:D").AutoFit
Range("A2").Select
ActiveWindow.FreezePanes = True
ActiveWorkbook.Saved = True
Application.StatusBar = False
End Sub
As stated in the MSDN Article, which I have already provided in the comments above, you can bind with MS Outlook either by Late Binding (LB) or Early Binding (EB) from MS Excel.
Now what exactly is LB and EB? For this I would again direct you to another MSDN link.
When you are using EB, you have to set a reference to the relevant application from Tools ~~> References and set your reference to the relevant Outlook Object Library. For example
In Layman Terms, Excel now understands what Outlook and MAPIFolder is. Similarly olFolderInbox is an Outlook constant which has a value of 6. So your original code would have worked without any errors if you would have set the reference.
When you are usign LB, you do not set a reference. You declare your objects as Objects. There are analyzed by Excel during runtime. More about this has already been covered in the link above. Also since we are late binding, we have to explicitly use 6 instead of olFolderInbox as that is what it's value is.
Hope this sets you on the right track. Do ask questions if you have any.