Related
Hello at the moment I currently have code that generates a seried of hyperlinks in a table that when clicked reference back to a cell on a different sheet contained in the workbook book. See code below.
Report.Hyperlinks.Add Anchor:=Report.Cells(LineNum, 1), Address:="", SubAddress:="Data!A" & (Counter - 1), TextToDisplay:="Link to Data"
The variable counter is the cell in which the data I am linking to is located and Data is the sheet it is contained in. Report is the worksheet to which I am writing the hyperlinks too.
The issue that I am encountering is that when data is either removed or added in the "Data" sheet the hyperlink in the "report" sheet will then link to the wrong cell thus rendering it useless. So to conclude is their a way to generate a dynamic hyperlink that changes based on edits (only line removals not column removal) to endure the hyperlinks link back to the correct data? Thank you for you help.
Full while loop as requested
DaysInCombo = 0
DaysInYear = DateSerial(YearA + 1, 1, 1) - DateSerial(YearA, 1, 1)
ExtraColNumber = Data.UsedRange.Columns.Count + 1
UltimateCount = Data.UsedRange.Rows.Count
Do While Data.Cells(Counter, 4).Value <> ""
'Check if at new position the address or meter number has changed
If Data.Cells(Counter, 4).Value <> CurrentAddress Or Data.Cells(Counter, 11).Value <> CurrentMeterNumber Then
'check num days to determine if there is an exception to be considered
If DaysInCombo = DaysInYear Then
Debug.Print "Good: " & CurrentAddress
Else
Debug.Print "Bad: " & CurrentAddress & " - " & DaysInCombo & " days - SN: " & CurrentMeterNumber
'compare meter number against the known lists
'if meter exists within the known lists then make note and place into a string
ExceptionStr = ""
ReasonStr = ""
TimeRangeStr = ""
'Data.Cells(Counter, 36).Value
'Compare against Meter Removal List
CheckCounter = 2
Do While MeterRemoval.Cells(CheckCounter, 1).Value <> ""
If CurrentMeterNumber = MeterRemoval.Cells(CheckCounter, 10).Value Or _
Right(CurrentMeterNumber, 8) = MeterInstall.Cells(CheckCounter, 10).Value Or _
(InStr(1, CurrentAddress, MeterRemoval.Cells(CheckCounter, 6).Value, vbTextCompare) = 1 And _
MeterRemoval.Cells(CheckCounter, 6).Value <> "") Then
Debug.Print "Success"
ExceptionStr = ExceptionStr & vbCrLf & "Meter Found on the Meter Removal list"
ReasonStr = ReasonStr & "Removed meter"
End If
CheckCounter = CheckCounter + 1
Loop
'Compare against Meter Install List
CheckCounter = 2
Do While MeterInstall.Cells(CheckCounter, 4).Value <> ""
If CurrentMeterNumber = MeterInstall.Cells(CheckCounter, 4).Value Or _
Right(CurrentMeterNumber, 8) = MeterInstall.Cells(CheckCounter, 4).Value Or _
InStr(1, CurrentAddress, MeterInstall.Cells(CheckCounter, 3).Value & " " & MeterInstall.Cells(CheckCounter, 2).Value, vbTextCompare) = 1 Then
Debug.Print "Success"
ExceptionStr = ExceptionStr & vbCrLf & "New Meter Installation"
ReasonStr = ReasonStr & "New meter"
End If
CheckCounter = CheckCounter + 1
Loop
'Compare against Meter Replace List
CheckCounter = 2
Do While MeterReplace.Cells(CheckCounter, 4).Value <> ""
If CurrentMeterNumber = MeterReplace.Cells(CheckCounter, 4).Value Or _
Right(CurrentMeterNumber, 8) = MeterReplace.Cells(CheckCounter, 4).Value Or _
CurrentMeterNumber = MeterReplace.Cells(CheckCounter, 5).Value Or _
Right(CurrentMeterNumber, 8) = MeterReplace.Cells(CheckCounter, 5).Value Or _
InStr(1, CurrentAddress, MeterReplace.Cells(CheckCounter, 3).Value & " " & MeterReplace.Cells(CheckCounter, 2).Value, vbTextCompare) = 1 Then
Debug.Print "Success"
ExceptionStr = ExceptionStr & vbCrLf & "Replaced Meter"
ReasonStr = ReasonStr & "Replaced meter"
End If
CheckCounter = CheckCounter + 1
Loop
'Compare Address Against the Address change list
CheckCounter = 2
'needs work
Do While AddressChange.Cells(CheckCounter, 1).Value <> ""
If InStr(1, CurrentAddress, AddressChange.Cells(CheckCounter, 1).Value, vbTextCompare) = 1 Or _
(InStr(1, CurrentAddress, AddressChange.Cells(CheckCounter, 2).Value, vbTextCompare) = 1 And _
AddressChange.Cells(CheckCounter, 2).Value <> "") Then
Debug.Print CurrentAddress
Debug.Print AddressChange.Cells(CheckCounter, 1).Value
Debug.Print AddressChange.Cells(CheckCounter, 2).Value
Debug.Print "Success"
ExceptionStr = ExceptionStr & vbCrLf & "The address was changed"
ReasonStr = ReasonStr & "Address change"
End If
CheckCounter = CheckCounter + 1
Loop
'Meter Replace NMOG
CheckCounter = 2
Do While MeterReplaceNMOG.Cells(CheckCounter, 4).Value <> ""
If CurrentMeterNumber = MeterReplaceNMOG.Cells(CheckCounter, 4).Value Or _
Right(CurrentMeterNumber, 8) = MeterReplaceNMOG.Cells(CheckCounter, 4).Value Or _
InStr(1, CurrentAddress, MeterReplaceNMOG.Cells(CheckCounter, 3).Value & " " & MeterReplaceNMOG.Cells(CheckCounter, 2).Value, vbTextCompare) = 1 Then
Debug.Print "Success"
ExceptionStr = ExceptionStr & vbCrLf & "Replaced Meter NMOG"
ReasonStr = ReasonStr & "Replaced meter NMOG"
End If
CheckCounter = CheckCounter + 1
Loop
'Check if an exception was found
ExceptionFound = True
If ExceptionStr = "" Or ReasonStr = "" Then
ExceptionStr = "No Exception reason has been found automatically"
ExceptionFound = False
End If
If DateValue(FirstDateRead) > DateValue(Format(DateSerial(YearA, 1, 1))) Then
ExceptionStr = ExceptionStr & vbCrLf & "Meter Recording Started Mid Year"
TimeRangeStr = TimeRangeStr & "Started Mid Year"
End If
If DateValue(LastDateRead) < DateValue(Format(DateSerial(YearA + 1, 1, 1))) Then
ExceptionStr = ExceptionStr & vbCrLf & "Meter Recording Ended Mid Year"
If TimeRangeStr <> "" Then
TimeRangeStr = TimeRangeStr & " - "
End If
TimeRangeStr = TimeRangeStr & "Ended Mid Year"
End If
ExceptionStr = DaysInCombo & " days: " & vbCrLf & ExceptionStr
'The counter is decremented by 1 due to the logic within the loop
Data.Cells(Counter - 1, ExtraColNumber).Value = ExceptionStr
'Make report
'if expection found, then use one report, else other
If ExceptionFound = True Then
Set Report = Report_Auto
Else
Set Report = Report_Manual
End If
'get last line of report sheet
LineNum = Report.UsedRange.Rows.Count + 1
'copy some relevant details of the location to the report and give it a link back to the location in the data.
Application.ScreenUpdating = False
'Link
Report.Hyperlinks.Add Anchor:=Report.Cells(LineNum, 1), Address:="", SubAddress:="Data!A" & (Counter - 1), TextToDisplay:="Link to Data"
'Address
Report.Cells(LineNum, 2).Value = CurrentAddress
'MeterSN
Report.Cells(LineNum, 3).Value = CurrentMeterNumber
'MeterInstall
Report.Cells(LineNum, 4).Value = Data.Cells(Counter - 1, 13).Value
'FirstDate
Report.Cells(LineNum, 5).NumberFormat = "dd-mmm-yy"
Report.Cells(LineNum, 5).Value = Format(FirstDateBill, "dd-MMM-yy")
'LastDate
Report.Cells(LineNum, 6).NumberFormat = "dd-mmm-yy"
Report.Cells(LineNum, 6).Value = Format(LastDateBill, "dd-MMM-yy")
'FirstDate
Report.Cells(LineNum, 7).NumberFormat = "dd-mmm-yy"
Report.Cells(LineNum, 7).Value = Format(FirstDateRead, "dd-MMM-yy")
'LastDate
Report.Cells(LineNum, 8).NumberFormat = "dd-mmm-yy"
Report.Cells(LineNum, 8).Value = Format(LastDateRead, "dd-MMM-yy")
'ProratedDays
Report.Cells(LineNum, 9).Value = DaysInCombo
'RangeText
Report.Cells(LineNum, 10).Value = TimeRangeStr
'ExceptionText
Report.Cells(LineNum, 11).Value = ReasonStr
Application.ScreenUpdating = True
'clear the report value for the next iteration
Set Report = Nothing
Loop
I interited a sheet at work and there is no one who actually supports anything Excel related. My VBA is rather rusty and hence I hope that someone can help me out here.
I have the following code: It goes in error at line
If mesi(mese) = "JAN" Then anno = Int(Right(oggi, 2)) + 1 Else anno = Int(Right(oggi, 2)) and i get Run-time error '9': Subscript out of range
I have not changed anything and it used to work for a long time. I really appreciate any input
Many thanks
Public Function Pulsante1_Click()
Dim oggi As Date
Dim mesi(1 To 12) As String
Dim prossima_data As String
Dim squarto, sstagione As String
Dim sqa As Range
Dim valore As Double
Dim r As Integer
Dim c As Integer
Dim quarto As Integer
Dim mesi_spalm() As String
Dim valori_spalm() As Double
Dim valor() As Double
Dim anno, mese As Integer
ActiveSheet.Range("J2:K1000000").ClearContents
ActiveSheet.Range("M2:N1000000").ClearContents
ActiveSheet.Range("P2:Q1000000").ClearContents
ActiveSheet.Range("J2:K1000000").Interior.ColorIndex = xlNone
ActiveSheet.Range("M2:N1000000").Interior.ColorIndex = xlNone
ActiveSheet.Range("P1:Q1000000").Interior.ColorIndex = xlThemeColorLight2
mesi(1) = "JAN"
mesi(2) = "FEB"
mesi(3) = "MAR"
mesi(4) = "APR"
mesi(5) = "MAY"
mesi(6) = "JUN"
mesi(7) = "JUL"
mesi(8) = "AUG"
mesi(9) = "SEP"
mesi(10) = "OCT"
mesi(11) = "NOV"
mesi(12) = "DEC"
oggi = Date
mese = (Int(Mid(oggi, 4, 2)) + 1) Mod 12
If mesi(mese) = "JAN" Then anno = Int(Right(oggi, 2)) + 1 Else anno = Int(Right(oggi, 2))
prossima_data = mesi(mese) & Right(anno, 1)
'MsgBox (prossima_data)
If ActiveSheet.Cells(29, 5) = oggi Then
ActiveSheet.Cells(2, 10) = oggi + 1
ActiveSheet.Cells(2, 11) = ActiveSheet.Cells(29, 3)
i = 3
Else
i = 2
End If
If (ActiveSheet.Cells(3, 2) = prossima_data) And (ActiveSheet.Cells(3, 5) = Date) Then
ActiveSheet.Cells(i, 10) = mese & "/20" & anno
ActiveSheet.Cells(i, 11) = ActiveSheet.Cells(3, 3)
i = i + 1
mese = mese + 1
If mese = 13 Then
mese = 1
anno = anno + 1
End If
If InStr(ActiveSheet.Cells(4, 2), "#N/A") = 0 And (ActiveSheet.Cells(4, 5) = Date) Then
ActiveSheet.Cells(i, 10) = mese & "/20" & anno
ActiveSheet.Cells(i, 11) = ActiveSheet.Cells(4, 3)
i = i + 1
mese = mese + 1
If mese = 13 Then
mese = 1
anno = anno + 1
End If
End If
If InStr(ActiveSheet.Cells(5, 2), "#N/A") = 0 And (ActiveSheet.Cells(5, 5) = Date) Then
ActiveSheet.Cells(i, 10) = mese & "/20" & anno
ActiveSheet.Cells(i, 11) = ActiveSheet.Cells(5, 3)
i = i + 1
mese = mese + 1
If mese = 13 Then
mese = 1
anno = anno + 1
End If
End If
If InStr(ActiveSheet.Cells(6, 2), "#N/A") = 0 And (ActiveSheet.Cells(6, 5) = Date) Then
ActiveSheet.Cells(i, 10) = mese & "/20" & anno
ActiveSheet.Cells(i, 11) = ActiveSheet.Cells(6, 3)
i = i + 1
mese = mese + 1
If mese = 13 Then
mese = 1
anno = anno + 1
End If
End If
If InStr(ActiveSheet.Cells(7, 2), "#N/A") = 0 And (ActiveSheet.Cells(7, 5) = Date) Then
ActiveSheet.Cells(i, 10) = mese & "/20" & anno
ActiveSheet.Cells(i, 11) = ActiveSheet.Cells(7, 3)
i = i + 1
mese = mese + 1
If mese = 13 Then
mese = 1
anno = anno + 1
End If
End If
ElseIf ActiveSheet.Cells(4, 2) = prossima_data And (ActiveSheet.Cells(4, 5) = Date) Then
ActiveSheet.Cells(i, 10) = mese & "/20" & anno
ActiveSheet.Cells(i, 11) = ActiveSheet.Cells(4, 3)
i = i + 1
mese = mese + 1
If mese = 13 Then
mese = 1
anno = anno + 1
End If
If InStr(ActiveSheet.Cells(5, 2), "#N/A") = 0 And (ActiveSheet.Cells(5, 5) = Date) Then
ActiveSheet.Cells(i, 10) = mese & "/20" & anno
ActiveSheet.Cells(i, 11) = ActiveSheet.Cells(5, 3)
i = i + 1
mese = mese + 1
If mese = 13 Then
mese = 1
anno = anno + 1
End If
End If
If InStr(ActiveSheet.Cells(6, 2), "#N/A") = 0 And (ActiveSheet.Cells(6, 5) = Date) Then
ActiveSheet.Cells(i, 10) = mese & "/20" & anno
ActiveSheet.Cells(i, 11) = ActiveSheet.Cells(6, 3)
i = i + 1
mese = mese + 1
If mese = 13 Then
mese = 1
anno = anno + 1
End If
End If
If InStr(ActiveSheet.Cells(7, 2), "#N/A") = 0 And (ActiveSheet.Cells(7, 5) = Date) Then
ActiveSheet.Cells(i, 10) = mese & "/20" & anno
ActiveSheet.Cells(i, 11) = ActiveSheet.Cells(7, 3)
i = i + 1
mese = mese + 1
If mese = 13 Then
mese = 1
anno = anno + 1
End If
End If
End If
'MsgBox (mese & " " & anno)
'cercare in foglio reuters il quarter e se la data è di oggi allora moltiplicare il suo valore per i pesi in valori_spalm per ottenere i singoli valori mese
quarto = WorksheetFunction.Ceiling(mese / 3, 1)
squarto = quarto & "Q" & anno
r = 1
c = 1
Set sqa = ActiveSheet.Range("B10:B16").Find(squarto, LookIn:=xlValues)
If Not sqa Is Nothing Then
r = sqa.Row
c = sqa.Column
End If
While Not sqa Is Nothing And ActiveSheet.Cells(r, c + 3) = Date
If Not sqa Is Nothing And ActiveSheet.Cells(sqa.Row, sqa.Column + 3) = Date Then
valore = ActiveSheet.Cells(sqa.Row, sqa.Column + 1)
ReDim mesi_spalm(1 To 3)
Select Case quarto
Case 1
mesi_spalm(1) = mesi(1) & anno
mesi_spalm(2) = mesi(2) & anno
mesi_spalm(3) = mesi(3) & anno
Case 2
mesi_spalm(1) = mesi(4) & anno
mesi_spalm(2) = mesi(5) & anno
mesi_spalm(3) = mesi(6) & anno
Case 3
mesi_spalm(1) = mesi(7) & anno
mesi_spalm(2) = mesi(8) & anno
mesi_spalm(3) = mesi(9) & anno
Case 4
mesi_spalm(1) = mesi(10) & anno
mesi_spalm(2) = mesi(11) & anno
mesi_spalm(3) = mesi(12) & anno
End Select
For j = 1 To 3
If mesi(mese) & anno = mesi_spalm(j) Then Exit For
Next j
If j > 1 Then ReDim valor(1 To (j - 1)) Else ReDim valor(0)
For pp = 1 To (j - 1)
valor(pp) = ActiveSheet.Cells(i - pp, 11)
Next pp
valori_spalm = spalma_mesi(mesi_spalm, valor, valore)
For k = j To 3
ActiveSheet.Cells(i, 10) = mese & "/20" & anno
ActiveSheet.Cells(i, 11) = valori_spalm(k)
i = i + 1
mese = mese + 1
If mese = 13 Then
mese = 1
anno = anno + 1
End If
Next k
End If
quarto = WorksheetFunction.Ceiling(mese / 3, 1)
squarto = quarto & "Q" & anno
r = 1
c = 1
Set sqa = ActiveSheet.Range("B10:B16").Find(squarto, LookIn:=xlValues)
If Not sqa Is Nothing Then
r = sqa.Row
c = sqa.Column
End If
Wend
'MsgBox (mese & " " & anno)
'cercare in foglio reuters il season e se la data è di oggi allora moltiplicare il suo valore per i pesi in valori_spalm per ottenere i singoli valori mese
If mese < 10 And mese >= 4 Then sstagione = "S-" & anno Else sstagione = "W-" & anno
r = 1
c = 1
Set sqa = ActiveSheet.Range("B19:B20").Find(sstagione, LookIn:=xlValues)
If Not sqa Is Nothing Then
r = sqa.Row
c = sqa.Column
End If
While Not sqa Is Nothing And ActiveSheet.Cells(r, c + 3) = Date
If Not sqa Is Nothing And ActiveSheet.Cells(sqa.Row, sqa.Column + 3) = Date Then
valore = ActiveSheet.Cells(sqa.Row, sqa.Column + 1)
ReDim mesi_spalm(1 To 6)
Select Case InStr(sstagione, "S-")
Case Is > 0
mesi_spalm(1) = mesi(4) & anno
mesi_spalm(2) = mesi(5) & anno
mesi_spalm(3) = mesi(6) & anno
mesi_spalm(4) = mesi(7) & anno
mesi_spalm(5) = mesi(8) & anno
mesi_spalm(6) = mesi(9) & anno
Case Is = 0
mesi_spalm(1) = mesi(10) & anno
mesi_spalm(2) = mesi(11) & anno
mesi_spalm(3) = mesi(12) & anno
mesi_spalm(4) = mesi(1) & (anno + 1)
mesi_spalm(5) = mesi(2) & (anno + 1)
mesi_spalm(6) = mesi(3) & (anno + 1)
End Select
For j = 1 To 6
If mesi(mese) & anno = mesi_spalm(j) Then Exit For
Next j
If j > 1 Then ReDim valor(1 To (j - 1)) Else ReDim valor(0)
For pp = 1 To (j - 1)
valor(pp) = ActiveSheet.Cells(i - pp, 11)
Next pp
valori_spalm = spalma_mesi(mesi_spalm, valor, valore)
For k = j To 6
ActiveSheet.Cells(i, 10) = mese & "/20" & anno
ActiveSheet.Cells(i, 11) = valori_spalm(k)
i = i + 1
mese = mese + 1
If mese = 13 Then
mese = 1
anno = anno + 1
End If
Next k
End If
If mese < 10 And mese >= 4 Then sstagione = "S-" & anno Else sstagione = "W-" & anno
r = 1
c = 1
Set sqa = ActiveSheet.Range("B19:B20").Find(sstagione, LookIn:=xlValues)
If Not sqa Is Nothing Then
r = sqa.Row
c = sqa.Column
End If
Wend
'MsgBox (mese & " " & anno)
'cercare in foglio reuters il year e se la data è di oggi allora moltiplicare il suo valore per i pesi in valori_spalm per ottenere i singoli valori mese
r = 1
c = 1
Set sqa = ActiveSheet.Range("B23:B26").Find("20" & anno, LookIn:=xlValues)
If Not sqa Is Nothing Then
r = sqa.Row
c = sqa.Column
End If
While Not sqa Is Nothing And ActiveSheet.Cells(r, c + 3) = Date
If Not sqa Is Nothing And ActiveSheet.Cells(sqa.Row, sqa.Column + 3) = Date Then
valore = ActiveSheet.Cells(sqa.Row, sqa.Column + 1)
ReDim mesi_spalm(1 To 12)
mesi_spalm(1) = mesi(1) & anno
mesi_spalm(2) = mesi(2) & anno
mesi_spalm(3) = mesi(3) & anno
mesi_spalm(4) = mesi(4) & anno
mesi_spalm(5) = mesi(5) & anno
mesi_spalm(6) = mesi(6) & anno
mesi_spalm(7) = mesi(7) & anno
mesi_spalm(8) = mesi(8) & anno
mesi_spalm(9) = mesi(9) & anno
mesi_spalm(10) = mesi(10) & anno
mesi_spalm(11) = mesi(11) & anno
mesi_spalm(12) = mesi(12) & anno
For j = 1 To 12
If mesi(mese) & anno = mesi_spalm(j) Then Exit For
Next j
If j > 1 Then ReDim valor(1 To (j - 1)) Else ReDim valor(0)
For pp = 1 To (j - 1)
valor(pp) = ActiveSheet.Cells(i - pp, 11)
Next pp
valori_spalm = spalma_mesi(mesi_spalm, valor, valore)
For k = j To 12
ActiveSheet.Cells(i, 10) = mese & "/20" & anno
ActiveSheet.Cells(i, 11) = valori_spalm(k)
i = i + 1
mese = mese + 1
If mese = 13 Then
mese = 1
anno = anno + 1
End If
Next k
End If
r = 1
c = 1
Set sqa = ActiveSheet.Range("B23:B26").Find("20" & anno, LookIn:=xlValues)
If Not sqa Is Nothing Then
r = sqa.Row
c = sqa.Column
End If
Wend
'MsgBox (mese & " " & anno)
tro = mesi(mese) & anno
Set sqa = ThisWorkbook.Sheets("ICE").Range("A:A").Find(tro, LookIn:=xlValues)
While Not sqa Is Nothing
ActiveSheet.Cells(i, 10) = mese & "/20" & anno
ActiveSheet.Cells(i, 11) = ThisWorkbook.Sheets("ICE").Cells(sqa.Row, 5) / 1000
ActiveSheet.Cells(i, 10).Interior.Color = RGB(0, 255, 255)
ActiveSheet.Cells(i, 11).Interior.Color = RGB(0, 255, 255)
i = i + 1
mese = mese + 1
If mese = 13 Then
mese = 1
anno = anno + 1
End If
tro = mesi(mese) & anno
Set sqa = ThisWorkbook.Sheets("ICE").Range("A:A").Find(tro, LookIn:=xlValues)
Wend
Pulsante3_Click
End Function
Public Function spalma_mesi(mesi() As String, valo() As Double, media_imp As Double) As Variant
Dim sm() As Double
Dim variazione() As Double
Dim media As Double
Dim nummes As Integer
Dim trov As Range
ReDim sm(1 To UBound(mesi))
ReDim variazione(1 To UBound(mesi))
media_imp = media_imp * 1000
media = 0
nummes = 0
For i = LBound(mesi) To UBound(mesi)
Set trov = ThisWorkbook.Sheets("ICE").Range("A:A").Find(mesi(i), LookIn:=xlValues)
If Not trov Is Nothing Then
If Not IsEmpty(valo) And i <= UBound(valo) Then sm(i) = valo(i) * 1000 Else sm(i) = ThisWorkbook.Sheets("ICE").Cells(trov.Row, trov.Column + 4)
variazione(i) = ThisWorkbook.Sheets("ICE").Cells(trov.Row, trov.Column + 4)
media = media + variazione(i)
nummes = nummes + 1
End If
Next i
media = media / nummes
For ll = LBound(mesi) To UBound(mesi)
variazione(ll) = 1 - (variazione(ll) - media) / media
Next ll
For i = UBound(valo) + 1 To UBound(sm)
sm(i) = (1 - (media - sm(i)) / media) * media_imp
Next i
nummes = 0
media = 0
For i = LBound(sm) To UBound(sm)
nummes = nummes + 1
media = media + sm(i)
Next i
media = media / nummes
While Abs(media - media_imp) > 0.1
va = media_imp - media
For i = UBound(valo) + 1 To UBound(sm)
If va > 0 Then sm(i) = sm(i) + 0.1 Else sm(i) = sm(i) - 0.1
Next i
nummes = 0
media = 0
For i = LBound(sm) To UBound(sm)
nummes = nummes + 1
media = media + sm(i)
Next i
media = media / nummes
Wend
For i = LBound(sm) To UBound(sm)
sm(i) = sm(i) / 1000
Next i
spalma_mesi = sm
End Function
Because, as #Skaterhaz stated, LBOUND(mesi) equals 1 and (Int(Mid(12, 4, 2)) + 1) will return 0 you will need to add one to your formula.
Dim mesi(1 To 12) As String
mese = (Int(Mid(oggi, 4, 2)) + 1) Mod 12 + 1
At work I have excel 2013 and I have a for cicle that add new data to the series of a chart at every iteration.
It works flawlessly and at every iteration I can see the chart updating.
Now I tried the code on my home pc with excel 2016 and no matter what the chart won't update. I tried everything
dim chr as ChartObject
dim chrt as Chart
set chr = Sheet1.ChartObjects.Add
set chrt = chr.Chart
then I tried everything like
doevents
chr.refresh
sheet1.enablecalculation = true
application.screenupdating = true
chr.activate
Application.ontime Now + timeSerial(0,0,1), "wt"
sub wt
Application.wait + timeSerial(0,0,1)
end sub
anything you can think of .. it won't update
Any suggestion? thanks to everyone
EDIT: I found that it works if I add
Sheet1.ResetAllPageBreaks
at the end of each iteration, BUT it slows down the code too much
Sub risolutore()
Application.ScreenUpdating = True
' DICHIARAZIONE DELLE VARIABILI
Dim ws As Worksheet
Dim chr As ChartObject, chr2 As ChartObject
Dim rng As Range, rng2 As Range
Dim grafico As Chart, grafico2 As Chart
'''''''''''''''''''''''''''''''
' SHEET SETTING
Set ws = Foglio5
''''''''''''''''
For Each ch In ws.ChartObjects
ch.Delete
Next ch
'SETTAGGIO DELLE CELLE DI RIFERIMENTO'''''''''''
w_cells = ws.Range("B2:B9").Address
v_cell = ws.Range("B16").Address
s_cell = ws.Range(v_cell).Offset(1, 0).Address
m_cell = ws.Range(v_cell).Offset(2, 0).Address
sum_cell = ws.Range(v_cell).Offset(3, 0).Address
s_col = "F"
wci = "H"
wcf = "O"
nri = 14
ndati = 40
nrf = nri + ndati - 1
m_max = Application.WorksheetFunction.Max(ws.Range(w_cells).Offset(0, 1))
ws.Range(s_col & nri & ":" & wcf & nrf).ClearContents
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
DoEvents
' CICLO RISOLUTORE E GRAFICI
For i = nri To nrf
ws.EnableCalculation = False
ws.EnableCalculation = True
' MIN VAR PORTFOLIO
If i = nri Then
' SETTAGGI DEL RISOLUTORE PER IL MIN VAR PORTFOLIO
obj = ws.Range(s_col & i).Offset(0, 1).Address
'reset dei parametri del solver
Application.Run "Solver.xlam!SolverReset"
'Decido la funzione da ottimizzare
Application.Run "Solver.xlam!SolverOk", v_cell, 2, 0, w_cells, 1, "GRG Nonlinear"
' vincolo di rendimento atteso
'Application.Run "Solver.xlam!SolverAdd", m_cell, 2, obj
' vincolo di peso maggiore di 0
Application.Run "Solver.xlam!SolverAdd", w_cells, 3, "0"
' vincolo di peso minore di 1
Application.Run "Solver.xlam!SolverAdd", w_cells, 1, "=1"
' vincolo di somma pesi uguale a 1
Application.Run "Solver.xlam!SolverAdd", sum_cell, 2, "=1"
Application.Run "Solver.xlam!SolverOptions", , , , , , , , , , , , False
' avvio il solver
Application.Run "Solver.xlam!SolverSolve", True
ws.Range(s_col & i).Value = ws.Range(s_cell).Value
ws.Range(s_col & i).Offset(0, 1).Value = ws.Range(m_cell).Value
ws.Range(s_col & i).NumberFormat = "0.000%"
ws.Range(s_col & i).Offset(0, 1).NumberFormat = "0.000%"
ws.Range(wci & i & ":" & wcf & i).Value = Application.WorksheetFunction.Transpose(ws.Range(w_cells).Value)
ws.Range(wci & i & ":" & wcf & i).NumberFormat = "0.00%"
' DETERMINO I VALORI DEI RENDIMENTI PER IL GRAFICO
m_min = ws.Range(m_cell).Value
max_min = m_max - m_min
Dim v() As Variant
ReDim v(1 To ndati)
v(1) = m_min
For K = LBound(v) + 1 To UBound(v)
v(K) = v(K - 1) + max_min / (ndati - 1)
Next K
ws.Range(s_col & nri).Offset(0, 1).Resize(UBound(v) - LBound(v) + 1).Value = Application.WorksheetFunction.Transpose(v)
ws.Range(s_col & nri).Offset(0, 1).Resize(UBound(v) - LBound(v) + 1).NumberFormat = "0.000%"
' SETTAGGI DEL PRIMO GRAFICO
Set rng = ws.Range("Q13:V25")
Set chr = ws.ChartObjects.Add(Left:=rng.Left, Width:=rng.Width, Top:=rng.Top, Height:=rng.Height)
Set grafico = chr.Chart
grafico.ChartType = xlXYScatterSmooth
grafico.SeriesCollection.NewSeries
grafico.SeriesCollection(1).XValues = ws.Range(s_col & nri).Offset(0, 0)
grafico.SeriesCollection(1).Values = ws.Range(s_col & nri).Offset(0, 1)
grafico.Axes(xlCategory).MinimumScale = ws.Range(s_col & nri).Offset(0, 0) * 0.8
grafico.Axes(xlCategory).TickLabels.Orientation = 35
grafico.Axes(xlValue).MinimumScale = m_min * 0.9
grafico.Axes(xlValue).MaximumScale = m_max * 1.1
grafico.Legend.Delete
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' SETTAGGI DEL SECONDO GRAFICO
Set rng2 = ws.Range("Q26:V42")
Set chr2 = ws.ChartObjects.Add(Left:=rng2.Left, Width:=rng2.Width, Top:=rng2.Top, Height:=rng2.Height)
Set grafico2 = chr2.Chart
grafico2.ChartType = xlAreaStacked100
grafico2.HasTitle = False
grafico2.Legend.Position = xlLegendPositionBottom
grafico2.Axes(xlValue).MinimumScale = 0
For j = 1 To 8
grafico2.SeriesCollection.NewSeries
grafico2.SeriesCollection(j).XValues = ws.Range(s_col & nri & ":" & s_col & nri)
grafico2.SeriesCollection(j).Values = ws.Range(s_col & nri & ":" & s_col & nri).Offset(0, 2 + j - 1)
grafico2.SeriesCollection(j).Name = ws.Range(s_col & nri).Offset(-2, 2 + j - 1)
Next j
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' DETERMINO GLI ALTRI PORTAFOGLI EFFICIENTI
ElseIf i > nri Then
If i = nri + 1 Then
grafico.ChartType = xlXYScatterSmoothNoMarkers
End If
obj = ws.Range(s_col & i).Offset(0, 1).Address
'reset dei parametri del solver
Application.Run "Solver.xlam!SolverReset"
'Decido la funzione da ottimizzare
Application.Run "Solver.xlam!SolverOk", v_cell, 2, 0, w_cells, 1, "GRG Nonlinear"
' vincolo di rendimento atteso
Application.Run "Solver.xlam!SolverAdd", m_cell, 2, obj
' vincolo di peso maggiore di 0
Application.Run "Solver.xlam!SolverAdd", w_cells, 3, "0"
' vincolo di peso minore di 1
Application.Run "Solver.xlam!SolverAdd", w_cells, 1, "=1"
' vincolo di somma pesi uguale a 1
Application.Run "Solver.xlam!SolverAdd", sum_cell, 2, "=1"
Application.Run "Solver.xlam!SolverOptions", , , , , , , , , , , , False
' avvio il solver
Application.Run "Solver.xlam!SolverSolve", True
ws.Range(s_col & i).Value = ws.Range(s_cell).Value
ws.Range(s_col & i).NumberFormat = "0.000%"
ws.Range(wci & i & ":" & wcf & i).Value = Application.WorksheetFunction.Transpose(ws.Range(w_cells).Value)
ws.Range(wci & i & ":" & wcf & i).NumberFormat = "0.00%"
grafico.SeriesCollection(1).XValues = ws.Range(s_col & nri & ":" & s_col & i)
grafico.SeriesCollection(1).Values = ws.Range(s_col & nri & ":" & s_col & i).Offset(0, 1)
For j = 1 To 8
grafico2.SeriesCollection(j).XValues = ws.Range(s_col & nri & ":" & s_col & nrf)
grafico2.SeriesCollection(j).Values = ws.Range(s_col & nri & ":" & s_col & i).Offset(0, 2 + j - 1)
Next j
End If
Next i
Application.ScreenUpdating = True
MsgBox "Ottimizazione Completata", vbInformation
End Sub
Have you tried just changing the chart data?
I worked with charts and when i changed the data the chart changed instantly.
This script is giving me an error because it consumes too much resources. What can I do to fix that?
Dim oSht As Worksheet
Dim i As Long, j As Integer
Dim LRow As Long, LCol As Long
Dim Email1Col As Integer, Email2Col As Integer, Email3Col As Integer
Dim arr As Variant
Dim SplEmail3 As String
'Definitions
Set oSht = ActiveSheet
Email1Col = 6
Email2Col = 7
Email3Col = 8
'-----------
With oSht
'LRow = .Range("G" & .Rows.Count).End(xlUp).Row
LRow = 1048576
'LCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
For i = 2 To LRow
'If oSht.Rows(i + 1).EntireRow = 0 Then GoTo Skip
If Cells(i, Email1Col).Value <> "" Or Cells(i, Email3Col).Value <> "" Then
If Cells(i, Email2Col) <> "" Then
'email2 to new row + copy other data
Rows(i + 1).EntireRow.Insert
oSht.Rows(i + 1).EntireRow.Value = oSht.Rows(i).EntireRow.Value
Range(Cells(i + 1, Email1Col), Cells(i + 1, Email3Col)).ClearContents
Cells(i + 1, Email1Col) = Cells(i, Email2Col)
'email3 to new row + copy other data
End If
If Cells(i, Email3Col) <> "" Then
arr = Split(Cells(i, Email3Col), ",", , 1)
For j = 0 To UBound(arr)
'split into single emails
SplEmail3 = Replace((arr(j)), " ", "", 1, , 1)
'repeat the process for every split
Rows(i + 2 + j).EntireRow.Insert
oSht.Rows(i + 2 + j).EntireRow.Value = oSht.Rows(i).EntireRow.Value
Range(Cells(i + 2 + j, Email1Col), Cells(i + 2 + j, Email3Col)).ClearContents
Cells(i + 2 + j, Email1Col) = SplEmail3
Next j
End If
Range(Cells(i, Email2Col), Cells(i, Email3Col)).ClearContents
Else
Rows(i).EntireRow.Delete
End If
Skip:
Next i
sample data:
col1, col2,..., col6, col7 , col8
name, bla, ...,mail1,mail2,(mail3,mail4,mail5)
needs to become this:
col1, col2,..., col6
name, bla, ...,mail1
Note: I have tested this with very small piece of data.. Give it a try and if you are stuck then let me know. We will take it from there.
Let's say our data looks like this
Now we run this code
Sub Sample()
Dim oSht As Worksheet
Dim arr As Variant, FinalArr() As String
Dim i As Long, j As Long, k As Long, LRow As Long
Set oSht = ActiveSheet
With oSht
LRow = .Range("A" & .Rows.Count).End(xlUp).Row
arr = .Range("A2:H" & LRow).Value
i = Application.WorksheetFunction.CountA(.Range("G:H"))
'~~> Defining the final output array
ReDim Preserve FinalArr(1 To (LRow + i - 3), 1 To 6)
k = 0
For i = LBound(arr) To UBound(arr)
k = k + 1
FinalArr(k, 1) = arr(i, 1)
FinalArr(k, 2) = arr(i, 2)
FinalArr(k, 3) = arr(i, 3)
FinalArr(k, 4) = arr(i, 4)
FinalArr(k, 5) = arr(i, 5)
If arr(i, 6) <> "" Then FinalArr(k, 6) = arr(i, 6)
For j = 7 To 8
If arr(i, j) <> "" Then
k = k + 1
FinalArr(k, 1) = arr(i, 1)
FinalArr(k, 2) = arr(i, 2)
FinalArr(k, 3) = arr(i, 3)
FinalArr(k, 4) = arr(i, 4)
FinalArr(k, 5) = arr(i, 5)
FinalArr(k, 6) = arr(i, j)
End If
Next j
Next i
.Rows("2:" & .Rows.Count).Clear
.Range("A2").Resize(UBound(FinalArr), 6).Value = FinalArr
End With
End Sub
Output
You can use Power Query. Your comment led me to do some testing, and that can be done while recording a macro. For example, assuming your data is in a "table":
Sub createPQ()
ActiveWorkbook.Queries.Add Name:="Table1", Formula:= _
"let" & Chr(13) & "" & Chr(10) & " Source = Excel.CurrentWorkbook(){[Name=""Table1""]}[Content]," & Chr(13) & "" & Chr(10) & " #""Changed Type"" = Table.TransformColumnTypes(Source,{{""FirstName"", type text}, {""LastName"", type text}, {""blah1"", type text}, {""b lah2"", type text}, {""bla3"", type text}, {""email1"", type text}, {""email2"", type text}, {""email3"", type text}})," & Chr(13) & "" & Chr(10) & " #""Unpivoted Columns"" = Tab" & _
"le.UnpivotOtherColumns(#""Changed Type"", {""FirstName"", ""LastName"", ""blah1"", ""b lah2"", ""bla3""}, ""Attribute"", ""Value"")" & Chr(13) & "" & Chr(10) & "in" & Chr(13) & "" & Chr(10) & " #""Unpivoted Columns"""
Sheets.Add After:=ActiveSheet
With ActiveSheet.ListObjects.Add(SourceType:=0, Source:= _
"OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=Table1" _
, Destination:=Range("$A$1")).QueryTable
.CommandType = xlCmdSql
.CommandText = Array("SELECT * FROM [Table1]")
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.PreserveColumnInfo = False
.ListObject.DisplayName = "Table1_2"
.Refresh BackgroundQuery:=False
End With
End Sub
If your user adds data, and needs to refresh the query, Data Ribbon ► Connection tab ► Refresh (or you could create a button to do that if you prefer).
The unknown is how it will work on a DB of your size.
-- Before
-- After
I want to put this If in a macro but it gives me an error all the time. I dont know if "Or" is used correctly or not.
Dim SMAT As String
SMAT = "blahblahblah"
(...)
If Cells(h + 2, 24) <> SMAT Or SMBE Or SMES Or SMFR Or SMGB Or SMGR Or SMRO1 Or SMRO2 Or SMRO3 Or SMDE Then
C(j) = Cells(h + 2, 5)
Use a Select Case block instead:
Select Case Cells(H + 2, 24).Value
Case SMAT, SMBE, SMES, SMFR, SMGB, SMGR, SMR01, SMR02, SMR03, SMDE
Case Else
c(j) = Cells(H + 2, 5).Value
End Select
Or another way using Evaluate(), just for variety*:
varConditions = Array(SMAT, SMBE, SMES, SMFR, SMGB, SMGR, SMR01, SMR02, SMR03, SMDE)
If Evaluate("ISERROR(MATCH(" & Cells(H + 2, 24).Value & ",{" & _
Join(varConditions, ",") & "},0))") Then
c(j) = Cells(H + 2, 5).Value
End If
* This Evaluate method will work when the array contains numbers - if you are using strings you would have to wrap each string in additional quotation marks
Here is the correction
Dim SMAT As String
SMAT = "blahblahblah"
'(...)
If Cells(H + 2, 24) <> SMAT Or _
Cells(H + 2, 24) <> SMBE Or _
Cells(H + 2, 24) <> SMES Or _
Cells(H + 2, 24) <> SMFR Or _
Cells(H + 2, 24) <> SMGB Or _
Cells(H + 2, 24) <> SMGR Or _
Cells(H + 2, 24) <> SMRO1 Or _
Cells(H + 2, 24) <> SMRO2 Or _
Cells(H + 2, 24) <> SMRO3 Or _
Cells(H + 2, 24) <> SMDE Then
c(j) = Cells(H + 2, 5)
End If
Or Operator (Visual Basic)
The error is because you are trying to "talk" to VBA like a person do, but the or does not take the parameter of another or. You need to tell in every parameter of each or to tell the complete logical test
firstCheck = a > b Or b > c
firstCheck = Logical_test Or Logical_test