I have faced a strange issue(Maybe a bug) at Data Validation
When i use below code for data validation, Excel is creating a dropdown but add string as one line. But when i write the same string from Excel data validation menu, Excel is seperating the dropdown with multiple items which i want.
For example, lets say string is "A;B;C"
When i do it by VBA, dropdown shows "A;B;C" as 1 line but when i click data validation menu and write manually "A;B;C" , Excel is creating 3 lines of dropdown with "A" , "B" , "C"
It is totally strange behavior. You may see the code as below. I add video link to explain better.
https://streamable.com/a75kud
Public arrAddress As String
Sub DynamicDataVal()
Dim rng As Range
Dim cll As Range
Dim dValicationCount As Long
Dim un As String
Dim DValidationList As Range
Dim DValidationListString As String
Dim seper As String
Dim col As New Collection, a
Dim colIt As Variant
Dim arr() As Variant
un = "Sayin " & Environ("UserName")
On Error Resume Next
Set rng = Application.InputBox("Lutfen Veri Alanini Seciniz", un, ActiveCell.Address, , , , , 8)
If rng Is Nothing Then Exit Sub
Set cll = ActiveCell
dValicationCount = cll.SpecialCells(xlCellTypeSameValidation).Count
If dValicationCount = 0 Then
arr = rng.Offset(1, 0).Resize(rng.Resize(, 1).Cells.Count - 1, 1).Value
arrAddress = rng.Address(External:=True)
For Each a In arr
col.Add a, a
Next a
seper = ListSeperatorMod.GetListSeparator
For Each colIt In col
DValidationListString = DValidationListString & seper & colIt
Next colIt
DValidationListString = Right(DValidationListString, Len(DValidationListString) - 1)
On Error GoTo 0
With cll.Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
Formula1:=DValidationListString
End With
Else
If rng.Validation.Type <> 3 Then
Exit Sub
Else
'Will be done
End If
End If
On Error GoTo 0
End Sub
Private Declare Function GetLocaleInfo Lib "kernel32" Alias "GetLocaleInfoA" _
(ByVal Locale As Long, ByVal LCType As Long, ByVal lpLCData As String, ByVal cchData As Long) As Long
Private Declare Function GetUserDefaultLCID% Lib "kernel32" ()
Private Const LOCALE_SLIST = &HC
Public Function GetListSeparator() As String
Dim ListSeparator As String
Dim iRetVal1 As Long
Dim iRetVal2 As Long
Dim lpLCDataVar As String
Dim Position As Integer
Dim Locale As Long
Locale = GetUserDefaultLCID()
iRetVal1 = GetLocaleInfo(Locale, LOCALE_SLIST, lpLCDataVar, 0)
ListSeparator = String$(iRetVal1, 0)
iRetVal2 = GetLocaleInfo(Locale, LOCALE_SLIST, ListSeparator, iRetVal1)
Position = InStr(ListSeparator, Chr$(0))
If Position > 0 Then
ListSeparator = Left$(ListSeparator, Position - 1)
End If
GetListSeparator = ListSeparator
End Function
It's by design and it's the the same behavior you'd see if using VBA to enter a formula in a cell: you always use the "US" list separator , in VBA, and not (eg) the locale-specific separator such as ;.
This differs from entering a formula via the user interface, where you're always using the locale-specific separator.
So in VBA you might use:
Range("A1").Formula = "=MAX(A1, B2)"
and if your locale separator is ; then the formula shows up on the sheet as:
=MAX(A1; B2)
This alows the same VBA to function across different locales without modifications
Related
Trying to get an older VB.NET application working again. One feature builds a text string composed of text delimited by Tab/Return characters, then creates (via interop) an Excel Workbook, adds a Worksheet, and (desired) paste the text string into the worksheet.
Here is the code:
Private Function AddNewWorksheetToWorkbook(
ByVal theWorkbook As Workbook,
ByVal worksheetName As String,
ByVal textToPaste As String
) As Microsoft.Office.Interop.Excel.Worksheet
Dim newWorksheet As Microsoft.Office.Interop.Excel.Worksheet
newWorksheet = theWorkbook.Worksheets.Add()
newWorksheet.Name = worksheetName
theWorkbook.Save()
newWorksheet.Activate() 'All works fine, file saved, worksheet named and Active as desired
Dim app As Microsoft.Office.Interop.Excel.Application
app = newWorksheet.Application
If app.ActiveSheet.Name = newWorksheet.Name Then 'Just a test to make sure ActiveSheet is the one desired -- it is
Clipboard.SetText(textToPaste) 'Clipboard has text delimited by vbTab and vbReturn (a "plain" text table)
newWorksheet.Range("A1").Select() 'Cell "A1" is properly selected
newWorksheet.Paste() 'BOOM! Get System.Runtime.InteropServices.COMException: 'Microsoft Excel cannot paste the data.'
End If
theWorkbook.Save()
Return newWorksheet
End Function
As noted in the comments, all goes well until the Worksheet.Paste() method call.
I have tried variations on Paste() as well as PasteSpecial(), etc. No joy.
Keep getting System.Runtime.InteropServices.COMException: 'Microsoft Excel cannot paste the data.'
I am able to (manually, not through interop) click "Paste" in Excel and it works just fine.
I would be grateful for any insights from the stackoverflow community!
So, here is what I ended up doing to solve (actually avoid and solve) the problem I was facing. Here is how I altered the existing function.
Private Function AddNewWorksheetToWorkbook(
ByVal theWorkbook As Workbook,
ByVal worksheetName As String,
ByVal textToPaste As String
) As Microsoft.Office.Interop.Excel.Worksheet
Dim newWorksheet As Microsoft.Office.Interop.Excel.Worksheet
newWorksheet = theWorkbook.Worksheets.Add()
newWorksheet.Name = worksheetName
theWorkbook.Save()
newWorksheet.Activate() 'All works fine, file saved, worksheet named and Active as desired
Dim app As Microsoft.Office.Interop.Excel.Application
app = newWorksheet.Application
If app.ActiveSheet.Name = newWorksheet.Name Then
Dim rowCount As Integer = 0
Dim colCount As Integer = 0
Dim values(,) As String = ExtractTwoDimDataSet(pasteText, rowCount, colCount)
Dim oRange As Range
oRange = newWorksheet.Range(newWorksheet.Cells(1, 1), newWorksheet.Cells(rowCount, colCount))
oRange.Value = values
End If
theWorkbook.Save()
Return newWorksheet
End Function
The change, of course, is to not use the Clipboard at all (which users might appreciate) and assign the "two-dimensional" text array to a Cell range on the Worksheet. The function (yes, I know, ugly with return values and ByRef parameters) is as follows:
Private Shared Function ExtractTwoDimDataSet(tabAndCrLfDelimitedText As String, ByRef rowCount As Integer, ByRef colCount As Integer) As String(,)
rowCount = 0
colCount = 0
Dim rows() As String
Dim columns() As String
rows = Split(tabAndCrLfDelimitedText, vbCrLf)
rowCount = rows.Length
For Each line As String In rows
columns = Split(line, vbTab)
If columns.Length > colCount Then
colCount = columns.Length
End If
Next
Dim values(rowCount, colCount) As String
rows = Split(tabAndCrLfDelimitedText, vbCrLf)
Dim r As Integer = 0
For Each line As String In rows
columns = Split(line, vbTab)
Dim c As Integer = 0
For Each cell As String In columns
values(r, c) = cell
c = c + 1
Next
r = r + 1
Next
Return values
End Function
The end result does what it needs to do and the function above is fairly reusable but I marked it Private as it is not general-purpose, and depends on the vbCrLf and vbTab delimiters.
This is clearly in the spirit of advice from #Mary ...
Thanks for the views and suggestions from stackoverflow folks!
Hello Everyone
I've got this array formula in excel and I want to merge it in a VBA code but it gives me an error of Unable to set the FormulaArray property of the Range class (Error 1004)
Here is the formula after i ammended it in the code
"=IF(SUMPRODUCT(--(($D$2=$B9)*(E$7>=$D$3)*(E$7<=$D$4)*(NOT(E$6>=1))*(NOT(E$8='الجمعة'))))=1;VLOOKUP($D$5;LeavesTypes;2;0);"""")"
and here is the full code
Option Explicit
Option Base 1
Dim wrk As Workbook, DataSH As Worksheet, CurrentSH As Worksheet
Dim FirstCol As Integer, EmpRow As Integer, EmpID As String
Dim GetEmpRowLoop As Integer, StartingEmpCol As Integer
Dim StartColLoop As Integer, EndingEmpCol As Integer
Dim EndColLoop As Integer
Public Sub Macro1()
Set wrk = ThisWorkbook
Set DataSH = wrk.Worksheets("الاجازات ")
Set CurrentSH = wrk.ActiveSheet
If CurrentSH.Name = DataSH.Name Then
MsgBox "Please Navigate to an Active Sheet", vbCritical
Exit Sub
End If
EmpID = CurrentSH.Range("d2").Value
For GetEmpRowLoop = 9 To CurrentSH.Cells(Cells.Rows.Count, 2).End(xlUp).Row
If CurrentSH.Cells(GetEmpRowLoop, 2).Value = EmpID Then
EmpRow = GetEmpRowLoop
Exit For
End If
Next GetEmpRowLoop
For StartColLoop = 4 To CurrentSH.Cells(EmpRow, Cells.Columns.Count).End(xlToRight).Column
If CurrentSH.Cells(7, StartColLoop).Value = CurrentSH.Range("D3").Value Then
StartingEmpCol = StartColLoop
Exit For
End If
Next StartColLoop
For EndColLoop = 4 To CurrentSH.Cells(EmpRow, Cells.Columns.Count).End(xlToRight).Column
If CurrentSH.Cells(7, EndColLoop).Value = CurrentSH.Range("D4").Value Then
EndingEmpCol = EndColLoop
Exit For
End If
Next EndColLoop
CurrentSH.Range(Cells(EmpRow, StartingEmpCol), Cells(EmpRow, StartingEmpCol)).FormulaArray = _
"=IF(SUMPRODUCT(--(($D$2=$B9)*(E$7>=$D$3)*(E$7<=$D$4)*(NOT(E$6>=1))*(NOT(E$8='الجمعة'))))=1;VLOOKUP($D$5;LeavesTypes;2;0);"""")"
End Sub
I'm trying to place whether the formula itself or the result doesn't matter.
You'll need to replace the single quotes (') with double quotes (""). However, you'll need to double up on the quotes...
(NOT(E$8=""الجمعة""))
By the way, there's no need for SUMPRODUCT. The following should suffice...
.Formula = "=IF(($D$2=$B9)*(E$7>=$D$3)*(E$7<=$D$4)*(NOT(E$6>=1))*(NOT(E$8=""الجمعة""))=1;VLOOKUP($D$5;LeavesTypes;2;0);"""")"
I'm trying to figure this out and can't.
I keep getting an error: "Compile error - Argument not optional". I am supplying the arguments and they are set as Optional!
Trying to pass a string and an array to a function and count occurrences of the array strings within the string passed.
Code stops running at the line:
Public Function countTextInText(Optional text As String, Optional toCountARR As Variant) As Integer
with a "Compile error: Argument not optional" message highlighting the Val in the line:
For Each Val In toCountARR
Full code:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim nameR As Range
Dim colR As Range
Dim TKRcnt As Integer
Dim TKRarr() As Variant
TKRarr = Array("TKR", "THR", "Bipolar")
Dim ORIFcnt As Integer
Dim ORIFarr() As Variant
TKRarr = Array("ORIF", "Ilizarov", "PFN")
Set nameR = Range("P2:P9")
Set colR = Range("B2:B50,G2:G50,L2:L50")
For Each namecell In nameR
For Each entrycell In colR
If entrycell.text = namecell.text Then
TKRcnt = countTextInText(entrycell.Offset(0, 2).text, TKRarr)
ORIFcnt = countTextInText(entrycell.Offset(0, 2).text, TKRarr)
End If
Next entrycell
MsgBox (namecell.text & " TKR count: " & TKRcnt & " ORIF count: " & ORIFcnt)
Next namecell
End Sub
Public Function countTextInText(Optional text As String, Optional toCountARR As Variant) As Integer
Dim cnt As Integer
Dim inStrLoc As Integer
For Each Val In toCountARR
inStrLoc = InStr(1, text, Val)
While inStrLoc <> 0
inStrLoc = InStr(inStrLoc, text, Val)
cnt = cnt + 1
Wend
Next Val
Set countTextInText = cnt
End Function
Val is a VBA function which requires a single, mandatory, argument - therefore the compiler generates the message saying "Argument not optional" if you don't provide that argument. (MSDN documentation of Val)
It is a bad idea to use VBA function names as variable names, so I would recommend you don't use Val as a variable name - use myVal or anything else that VBA hasn't already used.
If you really want to use Val (and you are sure that you won't be needing to access the Val function at all), you can use it as a variable name if you simply declare it as such, e.g.
Dim Val As Variant
You will also have problems with your line saying
Set countTextInText = cnt
as countTextInText has been declared to be an Integer, and Set should only be used when setting a variable to be a reference to an object. So that line should be
countTextInText = cnt
For those coming late to this question because of the question's title, as I did, having received this error while using the .Find method -
In my case, the problem was that the variable I was Seting was not Dimd at top of function.
My Example
Sub MyTest()
Dim tst, rngAll
rngAll = [a1].CurrentRegion
tst = fnFix1Plus1InValues(ByVal rngAll As Range)
End Sub
Public Function fnFix1Plus1InValues(ByVal rngAll As Range) As Boolean
Dim t1, t2, arr, Loc '<=== Needed Loc added here
Set Loc = rngAll.Find(What:="+", LookIn:=xlValues, LookAt:=xlPart, MatchCase:=False)
If Not Loc Is Nothing Then
Do Until Loc Is Nothing
t1 = Loc.Value
If fnContains(t1, "+") Then
'Do my stuff
End If
Set Loc = rngAll.FindNext(Loc)
Loop
End If
End Function 'fnFix1Plus1InValues
I have a column in a spreadsheet.
The format of the data in each cell is aa-0001-xx.
I need to examine the whole column to find the highest value of the sequence number. this would be the substring from column4 thru column7.
I can find the sequence number using Mid(ActiveWorkbook.Sheets("Sheet1").Range("B2:B2"), 4, 4)
But I need to find the max sequence in the whole column.
I am doing this in VBA.
Any help would be appreciated.
Here is my code so far:
Private Sub CommandButton1_Click()
Dim sQuoteNumber As String
Dim sFileName As String
Dim sPathName As String
Dim checkit As String
'Log the Quote
'First, open the log file and determine the next sequential log number.
sPathName = "C:\Users\Rich\Documents\Bryan\BigProject\"
sFileName = "QuoteLog2016.xlsx"
ControlFile = ActiveWorkbook.Name
Workbooks.Open Filename:=sPathName & sFileName
'Create the new Quote Number
checkit = Mid(ActiveWorkbook.Sheets("Sheet1").Range("B2:B2"), 4, 4) ' This is a temp test line
If Mid(ActiveWorkbook.Sheets("Sheet1").Range("B2:B2"), 4, 4) = "" Then
sQuoteNumber = "16-0001"
Else
'find the biggest number
'Here I was looking to like pass the mid function to a Max function of some sort.
sQuoteNumber = "16-0002"
End If
MsgBox ("The new Quote Number is: " + sQuoteNumber)
'Save the log entry
Workbooks(sFileName).Close
All of the comments made to your answer would work well for you. It's also true that there's no evidence in your code at having attempted something, however rudimentary, and this is why answers to a rather trivial task are not forthcoming for you. Perhaps, in future, have a go at some kind of solution ( even if it feels more guesswork than anything) and people on this site will be much more supportive of you.
To set you on your way, you could make use of the Split() function which converts a String into a String array, separated by a nominated value - in the case of your quotations, you could use "-" as your separator. This might be easier than your Mid function and will deal with the case of different sized quotations.
The code below will get you started but you'd want some error handling in there to test, for example, that each cell splits appropriately or that any cells aren't blank. I'll leave all of that to you.
Option Explicit
Private mLastQuote As Long
Public Sub Test()
Initialise 'call this routine just once at the start of your project
MsgBox GetNextQuote(16) 'use the GetNextQuote() function to get next number
MsgBox GetNextQuote(16)
MsgBox GetNextQuote(16)
End Sub
Private Function GetNextQuote(prefix As Integer) As String
mLastQuote = mLastQuote + 1
GetNextQuote = CStr(prefix) & "-" & _
Format(mLastQuote, "000#")
End Function
Private Sub Initialise()
Const PATH_NAME As String = "C:\Users\Rich\Documents\Bryan\BigProject\"
Const FILE_NAME As String = "QuoteLog2016.xlsx"
Const QUOTE_COL As String = "B"
Dim wb As Workbook
Dim ws As Worksheet
Dim v As Variant
Dim r As Long
Dim parts() As String
Dim num As Long
Application.ScreenUpdating = False
Set wb = Workbooks.Open(PATH_NAME & FILE_NAME, True, True)
Set ws = wb.Worksheets("Sheet1")
'Read quote values into variant array
With ws
v = .Range(.Cells(2, QUOTE_COL), _
.Cells(.Rows.Count, QUOTE_COL).End(xlUp)) _
.Value2
End With
'Find max quote
For r = 1 To UBound(v, 1)
parts = Split(v(r, 1), "-") 'splits quote into 3 parts
num = CLng(parts(1)) 'index (1) is the middle part
If num > mLastQuote Then mLastQuote = num
Next
wb.Close False
Application.ScreenUpdating = True
End Sub
I'd like to be able to copy a cell and paste ONLY number formats. Unfortunately, there is no built-in option in the PasteSpecial command.
Is there a way to press the copy button, select some destination cells, run a macro, and be able to retrieve the copied cells in a way analogous to the Selection object in VBA so that I can use its properties?
The only alternative I can think of is pasting to a known empty range (very far away) and then using that intermediate range, as below:
Dim A As Range
Set A = Range("ZZ99999")
A.PasteSpecial Paste:=xlPasteAll
Selection.NumberFormat = A.NumberFormat
Thanks!
Find olelib.tlb on the Internet (Edanmo's OLE interfaces & functions). There should be plenty of download links. Download and reference from your VBA project (Tools - References).
Note that it does not contain any executable code, only declarations of OLE functions and interfaces.
Also you might notice it's quite big, about 550kb. You can extract only the needed interfaces from it and recompile to get a much lighter TLB file, but that is up to you.
(If you are really unhappy with a TLB, there is also the dark magic route where you don't need any TLBs at all because you create assembly stubs on the fly to call vTable methods directly, but I won't be feeling like porting the below code this way.)
Then create a helper module and put this code into it:
Option Explicit
' No point in #If VBA7 and PtrSafe, as the Edanmo's olelib is 32-bit
Private Declare Function OpenClipboard Lib "user32.dll" (ByVal hwnd As Long) As Long
Private Declare Function GetClipboardData Lib "user32.dll" (ByVal wFormat As Long) As Long
Private Declare Function CloseClipboard Lib "user32.dll" () As Long
Public Function GetCopiedRange() As Excel.Range
Dim CF_LINKSOURCE As Long
CF_LINKSOURCE = olelib.RegisterClipboardFormat("Link Source")
If CF_LINKSOURCE = 0 Then Err.Raise 5, , "Failed to obtain clipboard format CF_LINKSOURCE"
If OpenClipboard(0) = 0 Then Err.Raise 5, , "Failed to open clipboard."
On Error GoTo cleanup
Dim hGlobal As Long
hGlobal = GetClipboardData(CF_LINKSOURCE)
If hGlobal = 0 Then Err.Raise 5, , "Failed to get data from clipboard."
Dim pStream As olelib.IStream
Set pStream = olelib.CreateStreamOnHGlobal(hGlobal, 0)
Dim IID_Moniker As olelib.UUID
olelib.CLSIDFromString "{0000000f-0000-0000-C000-000000000046}", IID_Moniker
Dim pMoniker As olelib.IMoniker
olelib.OleLoadFromStream pStream, IID_Moniker, pMoniker
Set GetCopiedRange = RangeFromCompositeMoniker(pMoniker)
cleanup:
Set pMoniker = Nothing 'To make sure moniker releases before the stream
CloseClipboard
If Err.Number > 0 Then Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
End Function
Private Function RangeFromCompositeMoniker(ByVal pCompositeMoniker As olelib.IMoniker) As Excel.Range
Dim monikers() As olelib.IMoniker
monikers = SplitCompositeMoniker(pCompositeMoniker)
If UBound(monikers) - LBound(monikers) + 1 <> 2 Then Err.Raise 5, , "Invalid composite moniker."
Dim binding_context As olelib.IBindCtx
Set binding_context = olelib.CreateBindCtx(0)
Dim WorkbookUUID As olelib.UUID
olelib.CLSIDFromString "{000208DA-0000-0000-C000-000000000046}", WorkbookUUID
Dim wb As Excel.Workbook
monikers(LBound(monikers)).BindToObject binding_context, Nothing, WorkbookUUID, wb
Dim pDisplayName As Long
pDisplayName = monikers(LBound(monikers) + 1).GetDisplayName(binding_context, Nothing)
Dim raw_range_name As String ' Contains address in the form of "!SheetName!R1C1Local", need to convert to non-local
raw_range_name = olelib.SysAllocString(pDisplayName)
olelib.CoGetMalloc(1).Free pDisplayName
Dim split_range_name() As String
split_range_name = Split(raw_range_name, "!")
Dim worksheet_name As String, range_address As String
worksheet_name = split_range_name(LBound(split_range_name) + 1)
range_address = Application.ConvertFormula(ConvertR1C1LocalAddressToR1C1(split_range_name(LBound(split_range_name) + 2)), xlR1C1, xlA1)
Set RangeFromCompositeMoniker = wb.Worksheets(worksheet_name).Range(range_address)
End Function
Private Function SplitCompositeMoniker(ByVal pCompositeMoniker As olelib.IMoniker) As olelib.IMoniker()
Dim MonikerList As New Collection
Dim enumMoniker As olelib.IEnumMoniker
Set enumMoniker = pCompositeMoniker.Enum(True)
If enumMoniker Is Nothing Then Err.Raise 5, , "IMoniker is not composite"
Dim currentMoniker As olelib.IMoniker
Do While enumMoniker.Next(1, currentMoniker) = olelib.S_OK
MonikerList.Add currentMoniker
Loop
If MonikerList.Count > 0 Then
Dim res() As olelib.IMoniker
ReDim res(1 To MonikerList.Count)
Dim i As Long
For i = 1 To MonikerList.Count
Set res(i) = MonikerList(i)
Next
SplitCompositeMoniker = res
Else
Err.Raise 5, , "No monikers found in the composite moniker."
End If
End Function
Private Function ConvertR1C1LocalAddressToR1C1(ByVal R1C1LocalAddress As String) As String
' Being extra careful here and not doing simple Replace(Replace()),
' because e.g. non-localized row letter may be equal to localized column letter which will lead to double replace.
Dim row_letter_local As String, column_letter_local As String
row_letter_local = Application.International(xlUpperCaseRowLetter)
column_letter_local = Application.International(xlUpperCaseColumnLetter)
Dim row_letter_pos As Long, column_letter_pos As Long
row_letter_pos = InStr(1, R1C1LocalAddress, row_letter_local, vbTextCompare)
column_letter_pos = InStr(1, R1C1LocalAddress, column_letter_local, vbTextCompare)
If row_letter_pos = 0 Or column_letter_pos = 0 Or row_letter_pos >= column_letter_pos Then Err.Raise 5, , "Invalid R1C1Local address"
If Len(row_letter_local) = 1 And Len(column_letter_local) = 1 Then
Mid$(R1C1LocalAddress, row_letter_pos, 1) = "R"
Mid$(R1C1LocalAddress, column_letter_pos, 1) = "C"
ConvertR1C1LocalAddressToR1C1 = R1C1LocalAddress
Else
ConvertR1C1LocalAddressToR1C1 = "R" & Mid$(R1C1LocalAddress, row_letter_pos + Len(row_letter_local), column_letter_pos - (row_letter_pos + Len(row_letter_local))) & "C" & Mid$(R1C1LocalAddress, column_letter_pos + Len(column_letter_local))
End If
End Function
Credits go to Alexey Merson.
Here's one way. Obviously you'll have to change the range to suit your situation, but it should get you the general idea:
Dim foo As Variant
foo = Sheet1.Range("A1:A10").NumberFormat
Sheet1.Range("D1:D10").NumberFormat = foo
Which really can be simplified to:
Sheet1.Range("D1:D10").NumberFormat = Sheet1.Range("A1:A10").NumberFormat
and if all of your formats in the range are the same, you can just do:
Sheet1.Range("D1:D10").NumberFormat = Sheet1.Range("A1").NumberFormat
Enough rambling...you get the idea.