星期四, 十月 27, 2011

VBA code to handle Access Imports and Query

From ExcelExperts.com
VBA code to handle Access Imports and Query:

Vishesh's picture


Paste the following code in a general module

Public g_objConnection As ADODB.Connection
Public Const gc_strDBPath As String = "C:\Test.mdb"
Function blnConnectDatabase(strPath As String, strDBPass As String) As Boolean
' If blnFileExists(strPath) = False Then
' GoTo ErrH
' Exit Function
' End If
Set g_objConnection = New ADODB.Connection
On Error GoTo ErrH
g_objConnection.Open "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & _
strPath & ";Jet OLEDB:Database Password=" & strDBPass & ";"
On Error GoTo 0
blnConnectDatabase = True
GoTo ExitH
ErrH:
blnConnectDatabase = False
Set g_objConnection = Nothing
ExitH:
Application.StatusBar = False
End Function
Function blnTableExistsInDB(strTableName As String) As Boolean
Dim rst As ADODB.Recordset
Dim strTbl As String
strTbl = strTableName
Call blnConnectDB
Set rst = g_objConnection.OpenSchema(adSchemaTables)
If Left(strTbl, 1) = "[" And Right(strTbl, 1) = "]" Then
strTbl = Mid(strTbl, 2, Len(strTbl) - 2)
End If
rst.Filter = "TABLE_TYPE='TABLE' and TABLE_NAME='" & strTbl & "'"
On Error Resume Next
blnTableExistsInDB = (UCase(rst.Fields("TABLE_NAME").Value) = UCase(strTbl))
On Error GoTo 0
If Err.Number <> 0 Then blnTableExistsInDB = False
Set rst = Nothing
End Function
Function ExecuteDBQuery(strQuery As String, Optional rngTarget As Range, Optional blnHeader As Boolean) As ADODB.Recordset
Dim objRecordset As ADODB.Recordset
Dim intColIndex As Integer
Dim lngRowOffset As Long
On Error GoTo ErrH
Call blnConnectDB
If Not rngTarget Is Nothing Then
Set rngTarget = rngTarget.Cells(1, 1)
End If
Set objRecordset = New ADODB.Recordset
With objRecordset
.CursorLocation = adUseClient
'.Open strQuery, g_objConnection, adOpenForwardOnly, adLockReadOnly ', adCmdText
.Open strQuery, g_objConnection, adOpenDynamic, adLockOptimistic ', adCmdText

If Not rngTarget Is Nothing Then
If blnHeader = True Then
For intColIndex = 0 To objRecordset.Fields.Count - 1 'field names
rngTarget.Cells(1, intColIndex + 1).NumberFormat = "@"
rngTarget.Cells(1, intColIndex + 1).Value = .Fields(intColIndex).Name
rngTarget.Cells(1, intColIndex + 1).Font.Bold = True
Next intColIndex
lngRowOffset = 1
Else 'Without field names
lngRowOffset = 0
End If
If Application.Version < 12 And .RecordCount + rngTarget.Cells(lngRowOffset + 1, 1).Row > 65535 Then
MsgBox "Records upto row number 65535 can be accommodated. Rest will be ignored.", vbInformation, "Import"
ElseIf Application.Version >= 12 And objRecordset.RecordCount + rngTarget.Cells(lngRowOffset + 1, 1).Row > 1048576 Then
MsgBox "Records upto row number 1048576 can be accommodated. Rest will be ignored.", vbInformation, "Import"
End If
rngTarget.Cells(lngRowOffset + 1, 1).CopyFromRecordset objRecordset ' the recordset data
End If
End With
Set ExecuteDBQuery = objRecordset
ErrH:
Set objRecordset = Nothing
If Err.Number <> 0 Then
'MsgBox Err.Description, vbCritical, "Error"
'MsgBox "Database Query Error"
End If
End Function
Sub DropTable(ParamArray strTableName() As Variant)
Dim x As Integer
For x = LBound(strTableName) To UBound(strTableName)
If blnTableExistsInDB(CStr(strTableName(x))) = True Then
Call ExecuteDBQuery("Drop Table " & CStr(strTableName(x)))
End If
Next x
End Sub
Function blnConnectDB() As Boolean
Dim blnCon As Boolean
blnCon = True
If g_objConnection Is Nothing Then
blnCon = blnConnectDatabase(gc_strDBPath, "")
ElseIf Not g_objConnection.State = 1 Then
blnCon = blnConnectDatabase(gc_strDBPath, "")
End If
blnConnectDB = blnCon
End Function
Sub CompactDB()
Dim lngRes As Long
Call CloseDB
lngRes = DatabaseCompact(gc_strDBPath)
If lngRes = 0 Then
'MsgBox "Succeeded in compacting database...", vbInformation
Else
'MsgBox Error(lngRes)
Application.StatusBar = "Unable to clean database..."
End If
End Sub
Function DatabaseCompact(strDBPath As String, Optional strDBPass As String = "") As Long
On Error GoTo ErrFailed
'Delete the existing temp database
If Len(Dir$(strDBPath & ".tmp")) Then
VBA.Kill strDBPath & ".tmp"
End If
With CreateObject("JRO.JetEngine")
If strDBPass = "" Then 'DB without password
.CompactDatabase "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strDBPath, "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strDBPath & ".tmp;Jet OLEDB:Encrypt Database=True"
Else 'Password protected db
.CompactDatabase "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strDBPath & ";Jet OLEDB:Database Password=" & strDBPass, "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strDBPath & ".tmp;Jet OLEDB:Encrypt Database=True;Jet OLEDB:Database Password=" & strDBPass
End If
End With
On Error GoTo 0
VBA.Kill strDBPath 'Delete the existing database
Name strDBPath & ".tmp" As strDBPath 'Rename the compacted database
ErrFailed:
DatabaseCompact = Err.Number
End Function
Sub CloseDB()
If Not g_objConnection Is Nothing Then
If g_objConnection.State = 1 Then g_objConnection.Close
End If
Set g_objConnection = Nothing
End Sub


星期二, 十月 11, 2011

Filter values where Fruit=Banana OR Sales>70. In Other Words, How to use Advanced Filters?

From Chandoo.org
Filter values where Fruit=Banana OR Sales>70. In Other Words, How to use Advanced Filters?:

Filtering is a simple yet powerful way to analyze data. When you apply filters to any list of values, Excel gives you some really useful pre-defined filters so that you can analyze the data in a variety of ways.


So, assuming you have data like this:


Sample Data for Advanced Filters - How to use Advanced Filters in Excel?


We all know how to filter data for Bananas.


We also know how to filter data where Sales > 70


But, what if you want to filter data such that Fruit is Banana OR Sales is more than 70?


Sounds tricky, Right?!?


Well, not so tricky. We can use Advanced Filters to do just this (and more).


Here is how we can filter values with Fruit=Banana OR Sales>70


1. Insert a few blank rows above your data


2. We will use this space to define the conditions for our Advanced Filters


As you can guess, to use Advanced Filters, you must write down the conditions for filtering in cells.


3. Now, set up cells like this.


Criteria Cells for Advanced Filters


4. In first row, write =”=Bananas” against Fruit column


Note: we use =”=Bananas” instead of =Bananas because whenever you write = Excel thinks you are writing a formula.


5. In second row, write >70 in the Sales column


If you write this in first row, then the filtering would happen for Fruit=Banana AND Sales>70


6. Now, select any cell with actual data and go to Data > Advanced Filter


Advanced Filter Option in Data Ribbon - Microsoft Excel


7. Select cells as shown below.


Advanced Filter Settings & Using it - Example


8. Click OK, and your list is filtered


Pretty cool, eh?


Some Tips about Advanced Filters:



  • Use Copy to Another Location Option to copy the filtered values elsewhere.

  • Excel creates a named range criteria upon the first time you apply advanced filters. As you can guess, this range contains the filtering criteria. With some creativity, you can dynamically change this (or create it) and make advanced filters even more advanced ;)

  • Do not select blank criteria rows: Make sure you only select criteria rows with some data in them. Otherwise, Excel will not filter.

  • Use with VBA: Advanced filters are pretty powerful & very fast. So, if you need to process a large list and create a sub-list that meets a criteria, you can do that thru Advanced Filters and even automate the process with a bit of VBA (more on this during next 2 weeks).

  • Few more advanced filter tips on Contextures: Debra shares some really nice examples on advanced filters. Check them out.


Download Advanced Filter Example Workbook:


Click here to download Excel workbook with Advanced Filter Example. Play with it to understand how you can filter like a fine coffee maker.


Do you use Advanced Filters?


I have rarely used advanced filters before writing this example. A reader’s email prompted me to learn this technique. And now, I am very eager to play with this so that I can share few more awesome implementations with you.


What about you? Do you use Advanced Filters? What do you use them for? What are your favorite tips & ideas? Please share using comments.


More Tips on using Data Filters:





星期三, 十月 05, 2011

Offset() function to Calculate IRR for Dynamic Range

From Chandoo.org
Offset() function to Calculate IRR for Dynamic Range:
Offset() function to Calculate IRR for Dynamic Range

When you start the project can you be sure, for how long will you operate it? A VC gives you funds to buy a commercial project. You are to operate the project for some time and then sell it off! Can you tell me today, when you will sell?

Real world is dynamic and business situations keep changing! Your excel is not that dynamic, when you use the IRR function and tell it to calculate the IRR, you show fixed cash flows! These cash flows are dynamic.

Not to worry! We have Offset function to our rescue!

What is the Offset() function

In my opinion it is one of the most versatile (And dangerous) functions to use. On the face of it, it is a simple function – As the name suggests, it just offsets your reference.

Offset( range, rows, columns, height, width )


image

clip_image002

So in the illustrated example, it starts from the C8 cell, moves 0 rows and 0 columns and then gives an array of size 5 x 5 to the sum function!

The difference – Now Offset is NOT returning a value. It is returning references to arrays!

So what can you do with this function?

Ah… you can do a lot! It can change diapers of your kids as well :-) . Right now we will see, how it can introduce unparalleled flexibility in your models.

So the VC we were speaking about – gives you USD 1000. You propose to operate the commercial complex for 4 years and post that sell it off for USD 1200.

But then you are not certain if the economic & business conditions would be such that you need to operate it for 4 or 5 or even 6 years. You want a flexibility in the model to “Dynamically Update” itself.


offset

How do we implement this?

The first step is to find the last cash flow in the assumption. I do that simply by counting the number of cash flows. It indicates the number of years that you run the business.

clip_image006

Once I have the number of cash flows with my, I dynamically return the size of the cash flow range using the offset function and input that to IRR function.

clip_image008

Since the offset returns reference to the array of cash flows, I can give that as an argument to the IRR function and it gets me the IRR of the project!

If a new cash flow is entered, the count function would calculate it, pass it to the offset function, which would return the new range to IRR. Phew!!

Few more places, where you can use Offset function

Anywhere you want references to be returned, Offset function does come handy. Similarly I have found offset to be a very useful function if you are looking at creating scenarios, especially in Merger Modeling, Growth Assumptions, Economic Assumptions, etc. With the click of the mouse, it can completely update your model!

Beware

In my modeling experience I have found the following three functions to be quite versatile with the ability to surprise you with their power!

· Offset

· Indirect

· Index

They can return references. This is not usually what you expect Excel to do. So when you are not expecting they can return references to unknown ranges and surprise you. They can make understanding of model (for the reader of your model) fairly difficult and auditing your model difficult. So use them with care!

Do you use these functions?

These functions can make your financial model quite flexible. Do you use such functions in your models? Share your views and experience on making your model more flexible!

Templates to download

I have created a template for you, where the subheadings are given and you have to link the model to get the cash numbers! You can download the same from here. You can go through the case and fill in the yellow boxes. I also recommend that you try to create this structure on your own (so that you get a hang of what information is to be recorded).

Also you can download this filled template and check, if the information you recorded, matches mine or not!

Join our Financial Modeling Classes


We are glad to inform that our new financial modeling & project finance modeling online class is ready for your consideration. Please click here to learn more about the program & sign-up. Chandoo.org has partnered with Pristine to launch a Financial Modeling Course. For details click here. Financial Modeling using Excel - Online Classes by Chandoo.org & Pristine For any queries regarding the cash impact or financial modeling, feel free to put the comments in the blog or write an email to paramdeep@edupristine.com