Column range input as a number, so it can be changed - excel

I have 25 spreadsheets that have pie charts.
I need to loop through the spreadsheets and change where the pie charts get the information from. But I can't get the code to work. I am coming from this:
Sub ChangePieValues()
Dim sheetno As Integer
sheetno = 14
Sheets(sheetno).Activate
ActiveSheet.ChartObjects("Chart 1").Activate
ActiveChart.FullSeriesCollection(1).XValues = "=Worksheets(2)$BA$3:$BA$6"
ActiveChart.FullSeriesCollection(1).Values = "=Worksheets(2)$BB$3:$BB$6"
End Sub
I haven't added the loop yet as this is the easy part.
My problem is in the following line:
ActiveChart.FullSeriesCollection(1).XValues = "=Worksheets(2)$BA$3:$BA$6"
I thought I could write something like:
ActiveChart.FullSeriesCollection(1).XValues = "=Worksheets(2).((Range(55,3)):(Range(55,6))"
I am trying to change the Range of the XValues to a number so I can change that number as I go through the different spreadsheets.
How can I change the way I input the column index, so it can be changed by loops.

Based on your question and example code - where you're providing a String to Excel that refers to the range - I would suggest the following solution:
ActiveChart.FullSeriesCollection(1).XValues = _
"'" & Worksheets(2).Name & "'!" & Cells(3, 53).Address & ":" & Cells(6, 53).Address
However, a better way would be to provide the property with a Range object (instead of a string that refers to the range object). This should also work, like so:
ActiveChart.FullSeriesCollection(1).XValues = _
Worksheets(2).Range(Worksheets(2).Cells(3, 53), Worksheets(2).Cells(6, 53))
To make that tidier to read though, I'd use:
With Worksheets(2)
ActiveChart.FullSeriesCollection(1).XValues = _
.Range(.Cells(3, 53), .Cells(6, 53))
End With
You were very close to achieving this in your example attempts, but as you were wrapping the location in double-quotes - Excel took them as if a String referencing a Range.

VBA ChartObjects: Change Source Data (SetSourceData)
In the workbook containing this code (ThisWorkbook), this will change the source data in the charts named Chart 1 of 25 consecutive worksheets, starting with the 14th worksheet, to the values in 25 consecutive columns in the 2nd worksheet, starting with column BA3:BA6.
Sub ChangeSourceData()
' Define constants.
' Source
Const sId As Variant = 2 ' name or index ('As Variant')
Const sFirstColumnAddress As String = "BA3:BA6"
' The number of source columns ('scCount') is equal
' to the number of destination worksheets.
Const scCount As Long = 25
' Destination
Const dFirstIndex As Long = 14 ' First Destination Worksheet
Const dChartName As String = "Chart 1" ' Each Worksheet's Chart Name
' Reference the workbook ('wb').
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Reference the source range ('srg').
Dim sws As Worksheet: Set sws = wb.Worksheets(sId)
Dim srg As Range: Set srg = sws.Range(sFirstColumnAddress).Resize(, scCount)
' Declare additional variables.
' Source
Dim sc As Long
' Destination
Dim dws As Worksheet
Dim dch As Chart
Dim dcho As ChartObject
Dim dIndex As Long
' Loop and apply.
' Loop through the columns ('sc') of the source range, indirectly...
For sc = 1 To scCount
' ... looping through the destination worksheets ('dIndex').
dIndex = dFirstIndex + sc - 1
' Reference the destination worksheet ('dws') by index,...
Set dws = wb.Worksheets(dIndex)
' ... to reference its 'ChartObject' ('dcho') by name ...
Set dcho = dws.ChartObjects(dChartName)
' ... to reference its 'Chart' ('dch') avoiding 'Activate'.
Set dch = dcho.Chart
' Set the new (one-column) data range for the chart.
dch.SetSourceData srg.Columns(sc)
'dch.FullSeriesCollection(1).ApplyDataLabels
Next sc
' Inform.
MsgBox "Source data changed.", vbInformation
End Sub

Related

Copying 1 column from multiple sheets into one sheet in the same workbook and them copy/paste a 2nd column from the same final sheet

I am relative novice in VBA and my goal is to automatically copy one column (B) from 3 named sheets (source sheets) and paste them in a new sheet and them repeat the process for column C and so on until a defined column (see image for my goal, in this case I wanted until column D of the source sheets). The structure of all sheets is identical. Columns consist of numeric values.
I have tried to write a code (see below) however I am getting run-time error 1004 for the commented line. Also, not sure if the code will do what I want to. What am I doing wrong and any tips to improve it?
Sub CopyColumns3()
Dim sheetNames As Variant
sheetNames = Array("temp_column", "normalized_column", "derivative_column")
Dim columnLetters As Variant
columnLetters = Array("B", "C", "D")
Dim i As Integer
Dim j As Integer
' Create a new sheet after the last sheet in the workbook
sheets.Add After:=sheets(sheets.Count)
' Set the name of the new sheet
sheets(sheets.Count).Name = "A_final"
For i = 0 To UBound(sheetNames)
For j = 0 To UBound(columnLetters)
sheets(sheetNames(i)).columns(columnLetters(j)).Copy
' Check if there are any empty columns in the Destination sheet
If sheets("A_final").Range("A1").End(xlToRight).Column = 256 Then
' If there are no empty columns, add a new column to the end of the sheet
sheets("A_final").columns(sheets("A_final").columns.Count).EntireColumn.Insert
End If
sheets("A_final").Select
' The next line causes the problem
sheets("A_final").Range("A1").End(xlToRight).Offset(0, 1).PasteSpecial
Next j
Next i
End Sub
enter image description here
Copy Columns
Sub ColumnsToNewSheet()
' Define constants.
Const DST_NAME As String = "A_final"
Const DST_FIRST_COLUMN As String = "A"
Dim sNames(): sNames = Array( _
"temp_column", "normalized_column", "derivative_column")
Dim sColumns(): sColumns = Array("B", "C", "D")
' Reference the workbook.
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Add a new sheet, rename it and reference the first Destination column.
Dim dws As Worksheet
Set dws = wb.Sheets.Add(After:=wb.Sheets(wb.Sheets.Count))
dws.Name = DST_NAME
Dim drg As Range: Set drg = dws.Columns(DST_FIRST_COLUMN)
' Copy the Source columns to the Destination columns.
' This does sh1-col1,sh2-col1,sh3-col3... as requested.
' If you need sh1-col1,sh1-col2,sh1-col3... switch the loops.
Dim srg As Range, sName, sColumn
For Each sColumn In sColumns
For Each sName In sNames
Set srg = wb.Sheets(sName).Columns(sColumn)
srg.Copy drg
Set drg = drg.Offset(, 1) ' next Destination column
Next sName
Next sColumn
' Inform.
MsgBox "Columns exported.", vbInformation
End Sub
I do not see why should you have that check for column 256.
However, when it is triggered, you call Range.Insert, which clears the CutCopyMode. Therefore, Range.PasteSpecial fails because there is nothing to paste.
You can move the check before the Range.Copy call, or get rid of it altogether.

trying to loop through data and paste it to another worksheet with a column offset

Hi I am trying to loop through data and paste it to another worksheet with a column offset
I copy some dates from a table (not the right way I know) after I paste them in the "Dynamisch voorblad" worksheet I copy the results from (G24:G27) to "Formule van Groei per week" (range B5)
I would like to copy this to the sheet "Formule van Groei per week" starting at "B5" and after each loop cycle to the next column. so B5 C5 D5 E5 F5 etc.
I was trying to achieve this with i
the code I've written:
Sub ggg()
For i = 2 To 21
'kies start
Sheets("WAKA").Range("C" & i).copy
Sheets("Dynamisch Voorblad").Range("C2").PasteSpecial Paste:=xlPasteValues
'kies eind
Sheets("WAKA").Range("D" & i).copy
Sheets("Dynamisch Voorblad").Range("C3").PasteSpecial Paste:=xlPasteValues
Sheets("Dynamisch Voorblad").Range("G24:G27").copy
Sheets("Blad13").Range(i, 5).PasteSpecial xlPasteValues
Next i
End Sub
Copy Values
Copying by assignment is more efficient and doesn't mess up the selection.
Option Explicit
Sub ggg()
' Reference the workbook.
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Reference the worksheets.
Dim wsDyn As Worksheet: Set wsDyn = wb.Worksheets("Dynamisch Voorblad")
Dim wsWak As Worksheet: Set wsWak = wb.Worksheets("WAKA")
Dim wsGro As Worksheet
Set wsGro = wb.Worksheets("Formule van Groei per week")
' Reference the ranges.
Dim rgDyn As Range: Set rgDyn = wsDyn.Range("G24:G27")
Dim fCellGro As Range: Set fCellGro = wsGro.Range("B5")
' Make it the same size as 'rgDyn'.
Dim rgGro As Range: Set rgGro = fCellGro.Resize(rgDyn.Rows.Count)
Dim i As Long
' Loop.
For i = 2 To 21
'kies start
wsDyn.Range("C2").Value = wsWak.Cells(i, "C").Value
'kies eind
wsDyn.Range("C3").Value = wsWak.Cells(i, "D").Value
' Copy the range.
rgGro.Value = rgDyn.Value
' Reference the next column range.
Set rgGro = rgGro.Offset(, 1)
Next i
End Sub

Sum the same table across different number of worksheets

So i have an excel file where i can enter the different projects that i want to analyse and the location of the files. Then a code to go and get the files and generate 2 sheets (from a template that i created) for each project entered and populate the data. These projects can vary the name and quantity.
My problem appears when i try to do a total table. Where i would go and get from the same cell in the different sheets the value and sum them. The number of sheets can change so i didnt manage to use a sheets.count, but the name of the sheets that relevant for this operation all start by "Total_".
So the beginning of the code that i have so far is:
`Sub refresh()
Parametre
Dim nbOnglet As Integer
Dim nbProjet As Integer
Dim name As String
Dim nametot As String
Dim A As String
Dim B As String
Dim idx As Integer
Dim iDebut As Integer
Dim values As Variant
Dim rng As Range
Dim xRng As Range
Dim x As Long
Dim vArray As Variant
Dim dSum As Double
Initialisation
iDebut = 9
Déterminer le nombre d'onglets du Classeur
nbOnglet = Sheets.Count
Déterminer le nombre de projet à traiter
folderpath = Range("C3").Value
Sheets("Sommaire").Select
nbLigne = Cells(10, "A").Value
x = 0
For idx = 1 To nbLigne
activate Récapitulatif
Sheets("Récapitulatif").Select
Define the variable name - tab name
A = "Total_"
B = Sheets("Sommaire").Cells(iDebut + idx, "D").Value
name = B
nametot = A & B`
Then for the sun i have tried different options but none appears to work for the entire table. I managed to get the good result for one cell by using the following:
x = x + sheets(nametot).range("F7").Value2
But couldn't do it for all the range (F7:CI31).
Other formula that i have tried was:
Set xRng = ThisWorkbook.Sheets(nbLigne).Range("K7:CI31")
xRng.FormulaR1C1 = "=SUM('" & ThisWorkbook.Sheets(nametot).name & "'!RC+'" & ThisWorkbook.Sheets(nametot).name & "'!RC)"
Although this gives the equation that i want since it is running in a loop, it calculates the same for each sheet and stops at the last one identified... So not doing what i would like to: sum the same cell across the different sheets named 'Total_XXXX' and present the value in the 'Récapitulatif' sheet.
I have been looking around internet and i can't really figure out a way to do it.
DO you have any ideas?
Thank you so much in advance
example of the table
Consolidate Worksheets
Links (Microsoft Docs)
Range.Address
Range.Consolidate
XlConsolidationFunction Enumeration
Description
In the workbook containing this code (ThisWorkbook), the following will consolidate (in this case sum up (xlSum)) all the same ranges (srcRange) in all worksheets with names starting with a specified string (srcLead) into another worksheet (tgtName) starting from a specified cell (tgtFirst).
The Code
Option Explicit
Sub consolidateWorksheets()
' Define constants.
Const srcRange As String = "K7:CI31"
Const srcLead As String = "Total_"
Const tgtName As String = "Récapitulatif"
Const tgtFirst As String = "A1"
' Define workbook.
Dim wb As Workbook
Set wb = ThisWorkbook
' Define Target Worksheet.
Dim tgt As Worksheet
Set tgt = wb.Worksheets(tgtName)
' Define R1C1-Style Source Ranges Address.
Dim rcRng As String
rcRng = tgt.Range(srcRange).Address(ReferenceStyle:=xlR1C1)
' Define Consolidation Array.
Dim Data As Variant
ReDim Data(1 To wb.Worksheets.Count)
' Declare variables.
Dim ws As Worksheet ' Current Source Worksheet
Dim CurrentName As String ' Current Source Worksheet Name
Dim n As Long ' Current Element in Consolidation Array
' Write full paths of Source Worksheets to Consolidation Array.
For Each ws In wb.Worksheets
CurrentName = ws.Name
If InStr(1, CurrentName, srcLead, vbTextCompare) = 1 Then
n = n + 1
Data(n) = "'" & ws.Name & "'!" & rcRng
End If
Next ws
' Validate and resize Consolidation Array.
If n = 0 Then
MsgBox "No worksheets to consolidate.", vbCritical, "Fail"
Exit Sub
End If
ReDim Preserve Data(1 To n)
' Consolidate.
tgt.Range(tgtFirst).Consolidate Sources:=Data, _
Function:=xlSum
' Inform user.
MsgBox "Data consolidated.", vbInformation, "Success"
End Sub

Concatenating 3 strings the outcome changes randomly

New to VBA coding and 1st time that I'm asking something, so give some slack if you see some dummy code.
I have an Excel Table which in column A has dates in the mm/dd/year format. I want to change it to dd/mm/year and in order to make some practice in VBA, I tried to do it via code (i have tried the Format Cells options but didn't work).
For a start I'm trying to rewrite the Date column in column H with the desired format using the following code:
Public Sub ChangingDateFormat()
Dim dest As Range
Dim dindx As Integer
Dim cll As Range
Dim x As String
Dim y As String
Dim z As String
'Establish where output goes
Set dest = Range("H2")
'Set counter for output rows
dindx = 0
'Establish your North Star reference
Set cll = Range("A2")
'Loop as long as anchor cell down isn't blanc
While cll.Offset(dindx, 0) <> ""
'Test if not empty; if not empty populate destination with data
If cll.Offset(dindx, 0) <> "" Then
x = Left(cll.Offset(dindx, 0), 2)
y = Mid(cll.Offset(dindx, 0), 4, 3)
z = Right(cll.Offset(dindx, 0), 5)
'True case: Output date
dest.Offset(dindx, 0) = y & x & z
'Increment row counter
dindx = dindx + 1
End If
'End While statement
Wend
End Sub
However, when the macro runs, some cells have the desired format and others not.
The Excel sheet looks like this:
My WorkSheet
Any ideas where the problem is? Pointing me to a direction would be deeply appreciated.
Thanks
Try using Format function like that (This is just sample) and try to implement in your code
Sub Test()
Dim r As Range
Set r = Range("A1")
r.Offset(, 3).Value = Format(r.Value, "dd/mm/yyyy")
End Sub
Excel Table (ListObject)
The following covers only the part I have an Excel Table which in column A has dates in the mm/dd/year format. I want to change it to dd/mm/year... i.e. the values in column A are real dates, not text.
Adjust the sheet and table names appropriately.
Since you are dealing with a ListObject (Table), you might consider using its properties.
The following procedures show how you can exploit some of them in two cases.
The first procedure will change the number format in the first column of the table, (not necessarily the first column of the worksheet). It is used when a column is always the first, so the header (title) can be changed.
The second procedure will try to find the given header (Header). If successful, it will apply the number formatting to the column where the header was found. It is used when the header (title) will never change, but the position of the column in the table might.
The Code
Sub IOnlyKnowTheColumnNumber()
' The n-th column of the Table, not the worksheet.
Const DateColumn As Long = 1
Dim wb As Workbook
Set wb = ThisWorkbook ' The workbook containing this code.
Dim ws As Worksheet
Set ws = wb.Worksheets("Sheet1")
Dim tbl As ListObject
Set tbl = ws.ListObjects("Table1")
' Define Date Column Range ('rng').
Dim rng As Range
Set rng = tbl.DataBodyRange.Columns(DateColumn)
' Apply formatting to Date Column Range.
rng.NumberFormat = "dd/mm/yyyy" ' "dd\/mm\/yyyy" for international.
' Inform user.
MsgBox "Number format applied.", vbInformation, "Success"
End Sub
Sub IOnlyKnowTheColumnTitle()
Const Header As String = "Date"
Dim wb As Workbook
Set wb = ThisWorkbook ' The workbook containing this code.
Dim ws As Worksheet
Set ws = wb.Worksheets("Sheet1")
Dim tbl As ListObject
Set tbl = ws.ListObjects("Table1")
' Define Header Row Range (Headers, Titles).
Dim hRng As Range
Set hRng = tbl.HeaderRowRange
' Try to calculate the Date Column Number.
Dim Temp As Variant
Temp = Application.Match(Header, hRng, 0)
If Not IsError(DateColumn) Then
' Define Date Column.
Dim DateColumn As Long
DateColumn = CLng(Temp)
' Define Date Column Range ('rng').
Dim rng As Range
Set rng = tbl.DataBodyRange.Columns(DateColumn)
' Apply formatting to Data Column Range.
rng.NumberFormat = "dd/mm/yyyy" ' "dd\/mm\/yyyy" for international.
' Inform user.
MsgBox "Number format applied.", vbInformation, "Success"
Else
' inform user.
MsgBox "Could not find '" & Header & "' column.", vbExclamation, "Fail"
End If
End Sub

Creating Invoices with VBA - Copy/Paste Loop

I am trying to create a VBA module, that takes data from a table in one worksheet and copies it to a second worksheet. This second worksheet should then be exported as a PDF.
The exporting part and naming the PDF is not an issue and I will only tackle this when the copying of the data from one sheet to the other works.
The structure of the table is that I have several rows that have data relevant to the invoice I want to fill on the second sheet and I would like that the macro loops through the whole file and only takes what it needs, but for now I am working on an easier version where I simply want to copy the data from a selection.
Option Explicit
Sub InvoiceCreator()
'create sheet
'Add info to sheet'
'save invoice sheet as PDF with name of customer
'reset sheet
'insert i+1 dataset
'loop til end
Dim sWS As Worksheet
Dim dWS As Worksheet
Dim sRange As Range
Dim sBNR As Range
Dim dBNR As Range
Dim sKNR As Range
Dim dKNR As Range
Dim sREF As Range
Dim dREF As Range
Dim sPRT As Range
Dim dPRT As Range
Dim sDAT As Range
Dim dDAT As Range
Dim sADR As Range
Dim dADR As Range
Dim sDES As String
Dim dDES As String
'Dim sPRC As Range
'Dim dPRC As Range
Dim i As Integer
Dim lastrow As Long
Set sWS = Sheets("Data")
Set dWS = Sheets("Sheet1")
Set sRange = Selection
Set sBNR = sRange.Cells(2, 7)
Set dBNR = dWS.Range("E4")
dBNR = sBNR.Value
Set sKNR = sRange.Cells(2, 2)
Set dKNR = dWS.Range("E6")
dKNR = sKNR.Value
Set sREF = sRange.Cells(2, 22)
Set dREF = dWS.Range("E8")
dREF = sREF.Value
Set sPRT = sRange.Cells(2, 23)
Set dPRT = dWS.Range("E10")
dPRT = sPRT.Value
Set sDAT = sRange.Cells(2, 4)
Set dDAT = dWS.Range("F4")
dDAT = sDAT.Value
lastrow = sRange.End(xlUp).Row
For i = 2 To lastrow
sDES = sRange.Cells(i, 12)
dDES = dWS.Range("A" & i + 23)
dDES = sDES
Next i
End Sub
Most of the code works and copies values from one sheet to the other, but I am stuck with the last loop bit.
I want to take the value of the string in a cell and copy it to a cell in the other sheet and then copy the cell value of the cell below and copy it to the other worksheet one cell below until the end of my selection. I am not getting any error, but it is not copying the data.
Any advice?

Resources