Issue No. 09 (July 15, 1999)
**********************************
COMMENTS
Welcome to the 9th issue of the Excel Experts E-letter (or EEE), by
David Hager. EEE is a semi-monthly publication. Feel free to distribute
copies of EEE to your friends and colleagues.
Back issues are available for download from the EEE web page located on John
Walkenbach's web site. New issues are normally available on the 1st and
16th of each month.
http://www.j-walk.com/ss/excel/eee/index.htm
**********************************
TOP EXCEL WEB SITES
An interesting product that allows Excel (version >5) to be used as an
Internet data browser has just been released. You can find the details on
this at:
http://www.inventure.com
**********************************
WORKSHEET FORMULA TIP
Created by Laurent Longre
This formula counts the number of cells in the discontiguous range that
contain a value greater than 20.
=INDEX(FREQUENCY((A1,A3,A5),20),2)
**********************************
POWER FORMULA TECHNIQUE
Created by Jan Karel Pieterse
This is an example of how to pass arguments to defined formulas. It consists
of the named formula called Myref (see below), which evaluates the string of
the formula of the "active" cell (the cell that calls one of the other named
formulas in this example). In order to use these formulas, a trick is
involved. The function must be called like this:
=IF(ROW(ref),NameOfTheDefinedFormula)
The Myref function finds the "Row(" part in the string of the formula and
takes all text between that and the first closing paren to be a valid cell
reference. Myref in part is used as an argument to the other functions.
Define Myref as:
=MID(GET.CELL(6,A1),FIND("ROW(",GET.CELL(6,A1))+4,FIND(")",GET.CELL(6,A1))-
FIND("ROW(",GET.CELL(6,A1))-4)
Please take into account, that when defining this formula:
- your active cell HAS TO BE cell A1
- You should NOT use absolute refs (no dollar signs)
- You should NOT use sheetrefs ("Sheet1!")
- When editing Myref, you should REMOVE ALL sheetrefs XL places there itself.
Note, that Myref has to be adapted for other language versions of Excel,
which may have a different word for the ROW function (change the string
"ROW(" and the two 4's in the formula accordingly).
IsFormula
=GET.CELL(48,INDIRECT(myref)))+0*now()
CellColor
=get.cell(63,indirect(MyRef))+0*now()
example:
=IF(ROW(D3),CellColor)
Shows the colournumber of the background of cell D3
RowIsHidden
=IF(GET.CELL(17,INDIRECT(Myref))=0,TRUE,FALSE)+0*now()
RowHeight
=GET.CELL(17,INDIRECT(Myref))+0*NOW()
**********************************
VBA CODE EXAMPLES
By John Green
This procedure finds cells on a worksheet containing data displayed as #####...
Sub FindIncorrectDataDisplay()
Dim rng As Range
For Each rng In ActiveSheet.UsedRange
If IsNumeric(rng.Value) And Left(rng.Text, 1) = "#" Then
MsgBox "Column too narrow for " & rng.Address
End If
Next rng
End Sub
By Nick Hodge
This procedure prints out all cell comments from a workbook.
First, create a text file on your desktop, (or change the reference in the
code), called test.txt and run the code below.
This will write each comment, on all worksheets, with it's address and sheet
no. to the txt file and close it.
Sub writeComments()
Dim mycomment As Comment
Dim mySht As Worksheet
Open "C:\Windows\Desktop\Test.txt" For Output As #1
For Each mySht In Worksheets
For Each mycomment In Worksheets(mySht.Name).Comments
Print #1, "From " & mycomment.Parent.Parent.Name _
& mycomment.Parent.Address _
& " Comes the comment: " _
& mycomment.Text
Next mycomment
Next mySht
Close #1
End Sub--
By Laurent Longre
This procedure looks up the Windows 95 serial number.
Declare Function RegOpenKeyExA Lib "Advapi32" _
(ByVal hkey As Long, ByVal lpszSubKey As String, _
ByVal dwReserved As Long, ByVal samDesired As Long, _
phkResult As Long) As Long
Declare Function RegQueryValueExA Lib "Advapi32" _
(ByVal hkey As Long, ByVal lpszValueName As String, _
lpwReserved As Long, lpdwType As Long, _
ByVal lpbData As String, lpcbData As Long) As Long
Declare Function RegCloseKey Lib "Advapi32" _
(ByVal hkey As Long) As Long
Sub Win95SerialNumber()
Dim hkey As Long
Dim Buffer As String
Dim lgBuf As Long
If RegOpenKeyExA(&H80000002, "Software\Microsoft\Windows" _
& "\CurrentVersion", 0, &H960277, hkey) Then Exit Sub
RegQueryValueExA hkey, "ProductId", 0, 1, Buffer, lgBuf
Buffer = Space(lgBuf)
If RegQueryValueExA(hkey, "ProductId", 0, 1, Buffer, lgBuf) = 0 _
Then MsgBox "Serial number = " & Buffer
RegCloseKey hkey
End Sub
By Chip Pearson
This procedure removes tabs and carriage returns from cells in the active
worksheet.
Sub CleanUp()
Dim TheCell As Range
For Each TheCell In ActiveSheet.UsedRange
With TheCell
If .HasFormula = False Then
.Value = Application.WorksheetFunction.Clean(.Value)
End If
End With
Next TheCell
End Sub
By Mark Lundberg
The following procedure is a workaround to the lack of a straightforward
programmatic way to turn off the 'Break on Unhandled Errors in Class Module'
option in the VBE.
Sub AClassCanBeAPainInThe()
Application.SendKeys "%{F11}%TO+{TAB}{RIGHT 2}%E~%{F4}"
End Sub
**********************************
POWER PROGRAMMING TECHNIQUES
Created by Laurent Longre
This example shows how to register functions into user-defined catagories and
provide descriptions for their arguments. The Auto_Open procedure registers
the two functions, Multiply and Divide in two categories Multiplication and
Division and provides descriptions of the input parameters.
Const Lib = """c:\windows\system\user32.dll"""
Option Base 1
Private Function Multiply(N1 As Double, N2 As Double) As Double
Multiply = N1 * N2
End Function
'==========================================
Private Function Divide(N1 As Double, N2 As Double) As Double
Divide = N1 / N2
End Function
'==========================================
Sub Auto_open()
Register "DIVIDE", 3, "Numerator,Divisor", 1, "Division", _
"Divides two numbers", """Numerator"",""Divisor """, "CharPrevA"
Register "MULTIPLY", 3, "Number1,Number2", 1, "Multiplication", _
"Multiplies two numbers", """First number"",""Second number """, _
"CharNextA"
End Sub
'==========================================
Sub Register(FunctionName As String, NbArgs As Integer, _
Args As String, MacroType As Integer, Category As String, _
Descr As String, DescrArgs As String, FLib As String)
Application.ExecuteExcel4Macro _
"REGISTER(" & Lib & ",""" & FLib & """,""" & String(NbArgs, "P") _
& """,""" & FunctionName & """,""" & Args & """," & MacroType _
& ",""" & Category & """,,,""" & Descr & """," & DescrArgs & ")"
End Sub
'==========================================
Sub Auto_close()
Dim FName, FLib
Dim I As Integer
FName = Array("DIVIDE", "MULTIPLY")
FLib = Array("CharPrevA", "CharNextA")
For I = 1 To 2
With Application
.ExecuteExcel4Macro "UNREGISTER(" & FName(I) & ")"
.ExecuteExcel4Macro "REGISTER(" & Lib & _
",""CharPrevA"",""P"",""" & FName(I) & """,,0)"
.ExecuteExcel4Macro "UNREGISTER(" & FName(I) & ")"
End With
Next
End Sub
Created by Bob Umlas and adaptation to a Function procedure
by John Walkenbach
This procedure allows for the access of information in a closed workbook
with VBA.
From Bob:
Here's a routine you can incorporate into your programs if you ever have
a need to retrieve data from a file without opening it. In the needed case,
I had to read any number of files (depending on user's selection from a
listbox) and determine whether range W11:W36 on sheet "General"
totalled zeroand do one thing if ANY file met that condition or another
thing if not.
At first, I thought I'd need to open each file, take the sum, then close
it again.
Not true.
By building a string which you can pass into the ExecuteExcel4Macro, you
can access this info directly, without opening the file, making it very fast:
Sub GetDataFromClosedFile()
filepath = "G:\fsoft\sos\data\ley"
FileName = "1cA10.sos" '<==this could change in a loop
sheetname = "General"
Strg = "sum('" & filepath & "\[" & FileName & "]" & sheetname &
"'!r11c23:r36c23)"
MsgBox ExecuteExcel4Macro(Strg)
End Sub
'In reality, it looked like this:
Sub GetDataFromClosedFile()
filepath = "G:\fsoft\sos\data\ley"
sheetname = "General"
For Each Fl In DialogSheets("DlgMulti").ListBoxes("MainList").List
Strg = "sum('" & filepath & "\[" & Fl & "]" & sheetname &
"'!r11c23:r36c23)"
Ans = ExecuteExcel4Macro(Strg)
If Ans > 0 Then Exit Sub
Next
'none > 0
'...rest of code goes here
End Sub
From John:
The GetValue function, listed below takes four arguments:
path: The drive and path to the closed file (e.g., "d:\files")
file: The workbook name (e.g., "99budget.xls")
sheet: The worksheet name (e.g., "Sheet1")
ref: The cell reference (e.g., "C4")
Private Function GetValue(path, file, sheet, range_ref)
' Retrieves a value from a closed workbook
Dim arg As String
' Make sure the file exists
If Right(path, 1) <> "\" Then path = path & "\"
If Dir(path & file) = "" Then
GetValue = "File Not Found"
Exit Function
End If
' Create the argument
arg = "'" & path & "[" & file & "]" & sheet & "'!" & _
Range(range_ref).Range("A1").Address(, , xlR1C1)
' Execute an XLM macro
GetValue = ExecuteExcel4Macro(arg)
End Function
**********************************
EXCEL 2000 INFORMATION
A workbook containing a hyperlink to a blank worksheet in the same
workbook, when saved as a Web page and viewed it in a Web browser, will
do nothing when you click the hyperlink. Excel does not save blank pages
by design when a workbook is saved as a web page to conserve disk space.
You must add some text to the blank page prior to saving it in this way
for the hyperlink to work. For more information on this, see:
http://support.microsoft.com/support/kb/articles/q221/0/64.asp
**********************************
DID YOU KNOW?...
that aside from the new COM add-ins in Office 2000 and using complied
xll/dll's, there is no good way to protect the code associated with
applications built in Excel. There are password crackers/retrievers
available that can hack the password from most if not all versions of Excel.
However, there is a way to add a layer of protection to your password for a
VB Project in Excel by using unprintable ASCII characters. The following
list shows those characters that can be used:
Alt-0128, Alt-0129, Alt-0141, Alt-0142,
Alt-0143, Alt-0144, Alt-0157, Alt-0158
There is no visual way to tell the difference among these characters, so a
password of suitable length will provide additional protection. It is likely
that code crackers can be made to display the corresponding ASCII code, but
at least it makes the password-breaking process a bit more difficult.
**********************************
Issue No.9 OF EEE (PUBLISHED 15Jul1999)
Next issue scheduled for 04Aug1999.
BY David Hager
dchager@compuserve.com
**********************************
Excel Expert Newsletter Archives
Here you'll find the archives of David Hager's Excel Expert's E-Letter, produced in 1999-2001. This information is old and unorganized, but it's here because it still contains lots of useful information. The newsletters contains quite a few links. Needless to say, most are no longer valid.
It's interesting to note that some of the key problems back then are still key problems today.