Save an Excel cell to a file - excel

I need to save the contents of a cell to an xml file named by another cell.
I need to perform this check for every row in the sheet.
Sub FormatRange()
Dim rng As Range
Dim row As Range
Dim cell As Range
Set rng = Range("A1:AG686")
For Each row In rng.Rows
Next row
End Sub
For each row I need to save cell AG to xml file named after cell C in the same row.
I am guessing I can use StreamWriter to write the file. I think the real problem is referencing the cells I need.

Sub FormatRange()
Dim rng As Range
Dim row As Range
Dim cell As Range
Set rng = Range("A2:AG686")
' Declare a FileSystemObject.
Dim fso As FileSystemObject
' Create a FileSystemObject.
Set fso = New FileSystemObject
' Declare a TextStream.
Dim stream As TextStream
' Create a TextStream.
For Each row In rng.Rows
Dim path As String
path = "C:\vba\" & row.Cells(1, 4) & ".xml"
' MsgBox (path + row.Cells(1, 33))
Set stream = fso.CreateTextFile(path, True)
stream.Write row.Cells(1, 33)
Next row
stream.Close
End Sub
Did it! Clustered my way through. Thanks for the suggestions.

Do you have to use VBA? I'm guessing if you know what a StreamWriter is you use C# or another .NET language. If so have a look at EPPlus, you can easily loop through your Excel sheet and use the .NET Framework.
http://epplus.codeplex.com/

Here is my flexible solution with right-click action and file choosing dialog:
Public Sub CellSaver()
Dim cell
For Each cell In Application.Selection.Cells
With Application.FileDialog(msoFileDialogSaveAs)
.Title = "Please select the file to save cell contents"
If .Show Then
With CreateObject("Scripting.FileSystemObject").CreateTextFile(.SelectedItems(1), True)
.Write cell
.Close
End With
End If
End With
Next cell
End Sub
Private Sub Workbook_Open()
With Application.CommandBars("Cell").Controls.Add(Temporary:=True)
.Caption = "Save to file"
.Style = msoButtonCaption
.OnAction = "'CellSaver'"
End With
End Sub
Credits go to:
#JMG's answer here
https://www.extendoffice.com/documents/excel/4375-excel-add-button-macro-to-right-click-menu.html
Can I simultaneously declare and assign a variable in VBA?
Excel VBA Cannot call function with onaction

Related

Is there a way to open Hyperlinks as an excel file?

I'm trying to write a code that will open some Hyperlink files by first concatenating ranges "E4:last row"(directory path) with "F4:last row" (file name). However i'm missing the concatenating step and what i have so far will open hyperlinks in one singel row in my explorer. How could I include the concatenating step and then open the links in excel instead for further editing?
Thank you!
Sub Hyperlink ()
Dim Sh As Worksheet
Dim Rng As Range
Dim Cell As Range
Set Sh = Worksheets("Tabelle1")
With Sh
Set Rng = .Range("E4:E9")
End With
For Each Cell In Rng
ThisWorkbook.FollowHyperlink Cell.Value
'<my edit steps will be included here later>
Next Cell
End Sub

Uipath error: "macro may not be available in this workbook"?

I am trying to retrieve cell addresses from an Excel sheet with UIPath invoke VBA activity.
I am new to VBA coding. I have written a function to retrieve cell address array and I have written a sub procedure to call that function.
I am calling the sub in UIPath activity named 'invoke VBA'. When I run this it says
Invoke VBA : Cannot run the macro 'Main'. The macro may not be
available in this workbook or all macros may be disabled.
This is the screen shot where I have enabled macros in Excel:
Sub Main(Amount As Integer)
Call findcellFunction(Amount)
End Sub
Function findcellFunction(Amount As Integer)As Collection
On Error Resume Next
Dim rngX As Range
Dim WS As Worksheet
Dim datax As Range
Dim cellAddress As Variant
Dim index As Integer
Dim iTotal As Integer
Dim CellArray
iTotal = 0
Set CellArray = New Collection
'Iterate until all cell values are found
For index=1 To Amount
Set rngX = Worksheets("rptBOMColorPrint").Range("A1:EZ50").Find("Colour Name", lookat:=xlPart)
If Not rngX Is Nothing Then
MsgBox "Found at " & rngX.Address
CellArray.Add rngX.Address
End If
Cells(rngX.Row,rngX.Column).Delete
iTotel =iTotal + index
Next index
'shows list that has been populated with cell addresses
For Each cellAddress In CellArray
MsgBox "list populated " & cellAddress
Range(cellAddress).Value = "Colour Name"
Next
CellArray = findcellFunction(Amount)
End Function
This is how I call the VBA from the UIPath activity.
When you include a .xlsx excel file instead of .xls file it works. It is because Uipath invoke VBA activity does not support .xls files as it is older version.

Excel macro to paste data into column X

I am looking for a macro to paste some data onto a moving range. I already have a cell that tells me the number of the next non empty column and this is the code I currently use:
Dim OpenFileName As String
Dim wb As Workbook
'Select and Open workbook
OpenFileName = Application.GetOpenFilename()
If OpenFileName = "False" Then Exit Sub
Set wb = Workbooks.Open(OpenFileName)
'Get data EXAMPLE
ThisWorkbook.Sheets("Teleselling 17").Range("I9:I289")*this should be dynamic, I want to paste data in a moving range*.Value = wb.Sheets("TELESELLING INBOUND").Range("L9:L289").Value
wb.Close SaveChanges:=False
MsgBox ("Done!")
Use the newly opened workbook/worksheet/range to define the scope of the value transfer.
with wb.workSheets("TELESELLING INBOUND").Range("L9:L289")
ThisWorkbook.workSheets("Teleselling 17").Range("XFD9").end(xltoleft).offset(0, 1).resize(.rows.count, .columns.count) = .value
end with

Setting a Sheet and cell as variable

I am new in VBA coding. Lets say I am retrieving value from Sheet3.Cell(23, 4) for a value, is there any way in the VBA code which let me set this as a variable?
For example, I have changed the interface and let the value stay at Sheet4.Cell(20,1), everywhere in my code which refer to Sheet3.Cell(23, 4) need to be changed to Sheet4.Cell(20, 1). I am thinking is there any best practice for coding VBA for situation like this?
Yes. For that ensure that you declare the worksheet
For example
Previous Code
Sub Sample()
Dim ws As Worksheet
Set ws = Sheets("Sheet3")
Debug.Print ws.Cells(23, 4).Value
End Sub
New Code
Sub Sample()
Dim ws As Worksheet
Set ws = Sheets("Sheet4")
Debug.Print ws.Cells(23, 4).Value
End Sub
Yes, set the cell as a RANGE object one time and then use that RANGE object in your code:
Sub RangeExample()
Dim MyRNG As Range
Set MyRNG = Sheets("Sheet1").Cells(23, 4)
Debug.Print MyRNG.Value
End Sub
Alternately you can simply store the value of that cell in memory and reference the actual value, if that's all you really need. That variable can be Long or Double or Single if numeric, or String:
Sub ValueExample()
Dim MyVal As String
MyVal = Sheets("Sheet1").Cells(23, 4).Value
Debug.Print MyVal
End Sub

How do I return the location of the marching ants in Excel? [duplicate]

This question already has answers here:
Can I Get the Source Range Of Excel Clipboard Data?
(3 answers)
Closed 2 years ago.
I know about Application.CutCopyMode, but that only returns the state of the CutCopyMode (False, xlCopy, or xlCut).
How do I return the address of the currently copied range in Excel using VBA? I don't need the currently selected range (which is Application.Selection.Address). I need the address of the range of cells with the moving border (marching ants) around it.
In other words, if you select a range of cells, hit CTRL+C, and then move the selection to another cell, I need the address of the cells that were selected when the user hit CTRL+C.
Thanks!
As far as I know you can't do that with vba. You can however code your own copy sub and store the source in a global variable.
Something like this:
Option Explicit
Dim myClipboard As Range
Public Sub toClipboard(Optional source As Range = Nothing)
If source Is Nothing Then Set source = Selection
source.Copy
Set myClipboard = source
End Sub
10 years later you still can't refer directly to a copied Range
(shown by the "marching ants border" aka "dancing border", "moving border").
But you can get its address by copying the cells as link to a temporary worksheet. There you can collect the desired range's address.
Private Sub ThereAreTheMarchingAnts()
Dim rngCopied As Range ' the copied range with the marching ants border
Dim rngSelected As Range ' the selected range
Dim tmpWorksheet As Worksheet ' a temporary worksheet
Dim c As Range ' a cell for looping
' Exit, if nothing was copied (no marching ants border):
If Not (Application.CutCopyMode = xlCopy Or Application.CutCopyMode = xlCut) Then Exit Sub
' Exit, if no range is selected (just for demonstration)
If Not TypeName(Selection) = "Range" Then Exit Sub
' remember selected Range:
Set rngSelected = Selection
' add a temporary sheet and paste copied cells as link:
Set tmpWorksheet = ActiveWorkbook.Sheets.Add
tmpWorksheet.Paste link:=True
' go through all pasted cells and get the linked range from their formula:
For Each c In tmpWorksheet.UsedRange
If rngCopied Is Nothing Then
Set rngCopied = Range(Mid(c.Formula, 2))
Else
Set rngCopied = Union(rngCopied, Range(Mid(c.Formula, 2)))
End If
Next c
' delete the temporary worksheet without asking:
Application.DisplayAlerts = False
tmpWorksheet.Delete
Application.DisplayAlerts = True
' show the addresses:
MsgBox "Copied Range: " & rngCopied.Address(0, 0, xlA1, True) & vbLf & _
"Selected Range: " & rngSelected.Address(0, 0, xlA1, True)
End Sub
The code also works with multiranges and also if the copied range and the selected range are on different sheets.
When you copy a Range, the address is copied to the Clipboard along with other formats. You can check that with Clipboard Viewer application.
So if you need the copied Range, get it from Clipboard. It will be something like> $A2:$B5 or similar
The only way i can think of doing this is tracking the last range selected with a global variable and then waiting until you think a copy action is done. Unfortunately neither is easy.
The following is a quick attempt that has two problems;
If you copy the same data twice it
isn't updated
If a copy or paste is
fired from another app, the results
may vary.
This is one of those last hope tricks when tracking events that don't really exist. Hope this helps.
''# Add a reference to : FM20.dll or Microsoft Forms 2.0
''# Some more details at http://www.cpearson.com/excel/Clipboard.aspx
Option Explicit
Dim pSelSheet As String
Dim pSelRange As String
Dim gCopySheet As String
Dim gCopyRange As String
Dim gCount As Long
Dim prevCBText As String
Dim DataObj As New MSForms.DataObject
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, _
ByVal Target As Excel.Range)
CopyTest
pSelSheet = Sh.Name
pSelRange = Target.Address
''# This is only so you can see it working
gCount = gCount + 1
application.StatusBar = gCopySheet & ":" & gCopyRange & ", Count: " & gCount
End Sub
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Source As Range)
CopyTest ''# You may need to call CopyTest from other events as well.
''# This is only so you can see it working
gCount = gCount + 1
application.StatusBar = gCopySheet & ":" & gCopyRange & ", Count: " & gCount
End Sub
Sub CopyTest()
Dim curCBText As String
Dim r As Range
DataObj.GetFromClipboard
On Error GoTo NoCBData
curCBText = DataObj.GetText
On Error Resume Next
''# Really need to test the current cells values
''# and compare as well. If identical may have to
''# update the gCopyRange etc.
If curCBText <> prevCBText Then
gCopySheet = pSelSheet
gCopyRange = pSelRange
prevCBText = curCBText
End If
Exit Sub
NoCBData:
gCopySheet = ""
gCopyRange = ""
prevCBText = ""
End Sub
Oh and excuse the wierd comments ''# they're just there to help the syntax highlighter of SO.
I think you can use this method
https://learn.microsoft.com/en-us/office/vba/api/Excel.Application.OnKey
This method assigns a function to the hot key Ctrl+C, every time this combination is used, the function will be triggered and you can get the address of the range.

Resources